Commit 645aa1a9 by Karl Schimpf

Convert Subzero's bitcode reader to generate ICE types.

Changes Subzero's bitcode reader to build and store ICE types, instead of using LLVM's types. Note: This code doesn't remove all uses of LLVM types. They are still used to check types for instructions and to generate function addresses. BUG=None R=jvoung@chromium.org, stichnot@chromium.org Review URL: https://codereview.chromium.org/625243002
parent d14b1a02
...@@ -53,57 +53,4 @@ Type TypeConverter::convertToIceTypeOther(llvm::Type *LLVMTy) const { ...@@ -53,57 +53,4 @@ Type TypeConverter::convertToIceTypeOther(llvm::Type *LLVMTy) const {
} }
} }
llvm::Type *TypeConverter::getLLVMIntegerType(unsigned NumBits) const {
switch (NumBits) {
case 1:
return LLVMTypes[IceType_i1];
case 8:
return LLVMTypes[IceType_i8];
case 16:
return LLVMTypes[IceType_i16];
case 32:
return LLVMTypes[IceType_i32];
case 64:
return LLVMTypes[IceType_i64];
default:
return NULL;
}
}
llvm::Type *TypeConverter::getLLVMVectorType(unsigned Size, Type Ty) const {
switch (Ty) {
case IceType_i1:
switch (Size) {
case 4:
return convertToLLVMType(IceType_v4i1);
case 8:
return convertToLLVMType(IceType_v8i1);
case 16:
return convertToLLVMType(IceType_v16i1);
default:
break;
}
break;
case IceType_i8:
if (Size == 16)
return convertToLLVMType(IceType_v16i8);
break;
case IceType_i16:
if (Size == 8)
return convertToLLVMType(IceType_v8i16);
break;
case IceType_i32:
if (Size == 4)
return convertToLLVMType(IceType_v4i32);
break;
case IceType_f32:
if (Size == 4)
return convertToLLVMType(IceType_v4f32);
break;
default:
break;
}
return NULL;
}
} // end of Ice namespace. } // end of Ice namespace.
...@@ -53,14 +53,6 @@ public: ...@@ -53,14 +53,6 @@ public:
/// Returns ICE model of pointer type. /// Returns ICE model of pointer type.
Type getIcePointerType() const { return IceType_i32; } Type getIcePointerType() const { return IceType_i32; }
/// Returns LLVM integer type with specified number of bits. Returns
/// NULL if not a valid PNaCl integer type.
llvm::Type *getLLVMIntegerType(unsigned NumBits) const;
/// Returns the LLVM vector type for Size and Ty arguments. Returns
/// NULL if not a valid PNaCl vector type.
llvm::Type *getLLVMVectorType(unsigned Size, Type Ty) const;
private: private:
// The list of allowable LLVM types. Indexed by ICE type. // The list of allowable LLVM types. Indexed by ICE type.
std::vector<llvm::Type *> LLVMTypes; std::vector<llvm::Type *> LLVMTypes;
......
...@@ -230,7 +230,7 @@ Type getCompareResultType(Type Ty) { ...@@ -230,7 +230,7 @@ Type getCompareResultType(Type Ty) {
SizeT getScalarIntBitWidth(Type Ty) { SizeT getScalarIntBitWidth(Type Ty) {
assert(isScalarIntegerType(Ty)); assert(isScalarIntegerType(Ty));
if (Ty == Ice::IceType_i1) if (Ty == IceType_i1)
return 1; return 1;
return typeWidthInBytes(Ty) * CHAR_BIT; return typeWidthInBytes(Ty) * CHAR_BIT;
} }
...@@ -245,4 +245,18 @@ const char *typeString(Type Ty) { ...@@ -245,4 +245,18 @@ const char *typeString(Type Ty) {
return "???"; return "???";
} }
void FuncSigType::dump(Ostream &Stream) const {
Stream << ReturnType << " (";
bool IsFirst = true;
for (const Type ArgTy : ArgList) {
if (IsFirst) {
IsFirst = false;
} else {
Stream << ", ";
}
Stream << ArgTy;
}
Stream << ")";
}
} // end of namespace Ice } // end of namespace Ice
...@@ -103,6 +103,43 @@ inline StreamType &operator<<(StreamType &Str, const Type &Ty) { ...@@ -103,6 +103,43 @@ inline StreamType &operator<<(StreamType &Str, const Type &Ty) {
return Str; return Str;
} }
/// Models a type signature for a function.
/// TODO(kschimpf): Consider using arena memory allocation for
/// the contents of type signatures.
class FuncSigType {
// FuncSigType(const FuncSigType &Ty) = delete;
FuncSigType &operator=(const FuncSigType &Ty) = delete;
public:
typedef std::vector<Type> ArgListType;
// Creates a function signature type with the given return type.
// Parameter types should be added using calls to appendArgType.
FuncSigType() : ReturnType(IceType_void) {}
void appendArgType(Type ArgType) { ArgList.push_back(ArgType); }
Type getReturnType() const { return ReturnType; }
void setReturnType(Type NewType) { ReturnType = NewType; }
SizeT getNumArgs() const { return ArgList.size(); }
Type getArgType(SizeT Index) const {
assert(Index < ArgList.size());
return ArgList[Index];
}
const ArgListType &getArgList() const { return ArgList; }
void dump(Ostream &Stream) const;
private:
// The return type.
Type ReturnType;
// The list of parameters.
ArgListType ArgList;
};
inline Ostream &operator<<(Ostream &Stream, const FuncSigType &Sig) {
Sig.dump(Stream);
return Stream;
}
} // end of namespace Ice } // end of namespace Ice
#endif // SUBZERO_SRC_ICETYPES_H #endif // SUBZERO_SRC_ICETYPES_H
...@@ -46,6 +46,114 @@ static cl::opt<bool> AllowErrorRecovery( ...@@ -46,6 +46,114 @@ static cl::opt<bool> AllowErrorRecovery(
cl::desc("Allow error recovery when reading PNaCl bitcode."), cl::desc("Allow error recovery when reading PNaCl bitcode."),
cl::init(false)); cl::init(false));
// Models elements in the list of types defined in the types block.
// These elements can be undefined, a (simple) type, or a function type
// signature. Note that an extended type is undefined on construction.
// Use methods setAsSimpleType and setAsFuncSigType to define
// the extended type.
class ExtendedType {
// ExtendedType(const ExtendedType &Ty) = delete;
ExtendedType &operator=(const ExtendedType &Ty) = delete;
public:
/// Discriminator for LLVM-style RTTI.
enum TypeKind { Undefined, Simple, FuncSig };
ExtendedType() : Kind(Undefined) {}
virtual ~ExtendedType() {}
ExtendedType::TypeKind getKind() const { return Kind; }
void Dump(Ice::Ostream &Stream) const;
/// Changes the extended type to a simple type with the given
/// value.
void setAsSimpleType(Ice::Type Ty) {
assert(Kind == Undefined);
Kind = Simple;
Signature.setReturnType(Ty);
}
/// Changes the extended type to an (empty) function signature type.
void setAsFunctionType() {
assert(Kind == Undefined);
Kind = FuncSig;
}
protected:
// Note: For simple types, the return type of the signature will
// be used to hold the simple type.
Ice::FuncSigType Signature;
private:
ExtendedType::TypeKind Kind;
};
Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) {
Ty.Dump(Stream);
return Stream;
}
Ice::Ostream &operator<<(Ice::Ostream &Stream, ExtendedType::TypeKind Kind) {
Stream << "ExtendedType::";
switch (Kind) {
case ExtendedType::Undefined:
Stream << "Undefined";
break;
case ExtendedType::Simple:
Stream << "Simple";
break;
case ExtendedType::FuncSig:
Stream << "FuncSig";
break;
default:
Stream << "??";
break;
}
return Stream;
}
// Models an ICE type as an extended type.
class SimpleExtendedType : public ExtendedType {
SimpleExtendedType(const SimpleExtendedType &) = delete;
SimpleExtendedType &operator=(const SimpleExtendedType &) = delete;
public:
Ice::Type getType() const { return Signature.getReturnType(); }
static bool classof(const ExtendedType *Ty) {
return Ty->getKind() == Simple;
}
};
// Models a function signature as an extended type.
class FuncSigExtendedType : public ExtendedType {
FuncSigExtendedType(const FuncSigExtendedType &) = delete;
FuncSigExtendedType &operator=(const FuncSigExtendedType &) = delete;
public:
const Ice::FuncSigType &getSignature() const { return Signature; }
void setReturnType(Ice::Type ReturnType) {
Signature.setReturnType(ReturnType);
}
void appendArgType(Ice::Type ArgType) { Signature.appendArgType(ArgType); }
static bool classof(const ExtendedType *Ty) {
return Ty->getKind() == FuncSig;
}
};
void ExtendedType::Dump(Ice::Ostream &Stream) const {
Stream << Kind;
switch (Kind) {
case Simple: {
Stream << " " << Signature.getReturnType();
break;
}
case FuncSig: {
Stream << " " << Signature;
}
default:
break;
}
}
// Top-level class to read PNaCl bitcode files, and translate to ICE. // Top-level class to read PNaCl bitcode files, and translate to ICE.
class TopLevelParser : public NaClBitcodeParser { class TopLevelParser : public NaClBitcodeParser {
TopLevelParser(const TopLevelParser &) = delete; TopLevelParser(const TopLevelParser &) = delete;
...@@ -96,23 +204,35 @@ public: ...@@ -96,23 +204,35 @@ public:
/// Changes the size of the type list to the given size. /// Changes the size of the type list to the given size.
void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); } void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); }
/// Returns the type associated with the given index. /// Returns the undefined type associated with type ID.
Type *getTypeByID(unsigned ID) { /// Note: Returns extended type ready to be defined.
// Note: method resizeTypeIDValues expands TypeIDValues ExtendedType *getTypeByIDForDefining(unsigned ID) {
// to the specified size, and fills elements with nullptr. // Get corresponding element, verifying the value is still undefined
Type *Ty = ID < TypeIDValues.size() ? TypeIDValues[ID] : nullptr; // (and hence allowed to be defined).
ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined);
if (Ty) if (Ty)
return Ty; return Ty;
return reportTypeIDAsUndefined(ID); if (ID >= TypeIDValues.size())
TypeIDValues.resize(ID+1);
return &TypeIDValues[ID];
} }
/// Defines type for ID. /// Returns the type associated with the given index.
void setTypeID(unsigned ID, Type *Ty) { Ice::Type getSimpleTypeByID(unsigned ID) {
if (ID < TypeIDValues.size() && TypeIDValues[ID] == nullptr) { const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Simple);
TypeIDValues[ID] = Ty; if (Ty == nullptr)
return; // Return error recovery value.
return Ice::IceType_void;
return cast<SimpleExtendedType>(Ty)->getType();
} }
reportBadSetTypeID(ID, Ty);
/// Returns the type signature associated with the given index.
const Ice::FuncSigType &getFuncSigTypeByID(unsigned ID) {
const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig);
if (Ty == nullptr)
// Return error recovery value.
return UndefinedFuncSigType;
return cast<FuncSigExtendedType>(Ty)->getSignature();
} }
/// Sets the next function ID to the given LLVM function. /// Sets the next function ID to the given LLVM function.
...@@ -137,7 +257,7 @@ public: ...@@ -137,7 +257,7 @@ public:
return DefiningFunctionsList[NumFunctionBlocks++]; return DefiningFunctionsList[NumFunctionBlocks++];
} }
/// Returns the LLVM IR value associatd with the global value ID. /// Returns the LLVM Function address associated with ID.
Function *getFunctionByID(unsigned ID) const { Function *getFunctionByID(unsigned ID) const {
if (ID >= FunctionIDValues.size()) if (ID >= FunctionIDValues.size())
return nullptr; return nullptr;
...@@ -241,18 +361,6 @@ public: ...@@ -241,18 +361,6 @@ public:
return TypeConverter.convertToLLVMType(IceTy); return TypeConverter.convertToLLVMType(IceTy);
} }
/// Returns the LLVM integer type with the given number of Bits. If
/// Bits is not a valid PNaCl type, returns nullptr.
Type *getLLVMIntegerType(unsigned Bits) const {
return TypeConverter.getLLVMIntegerType(Bits);
}
/// Returns the LLVM vector with the given Size and Ty. If not a
/// valid PNaCl vector type, returns nullptr.
Type *getLLVMVectorType(unsigned Size, Ice::Type Ty) const {
return TypeConverter.getLLVMVectorType(Size, Ty);
}
/// Returns the model for pointer types in ICE. /// Returns the model for pointer types in ICE.
Ice::Type getIcePointerType() const { Ice::Type getIcePointerType() const {
return TypeConverter.getIcePointerType(); return TypeConverter.getIcePointerType();
...@@ -274,7 +382,7 @@ private: ...@@ -274,7 +382,7 @@ private:
// The number of errors reported. // The number of errors reported.
unsigned NumErrors; unsigned NumErrors;
// The types associated with each type ID. // The types associated with each type ID.
std::vector<Type *> TypeIDValues; std::vector<ExtendedType> TypeIDValues;
// The set of function value IDs. // The set of function value IDs.
std::vector<WeakVH> FunctionIDValues; std::vector<WeakVH> FunctionIDValues;
// The set of global addresses IDs. // The set of global addresses IDs.
...@@ -289,43 +397,45 @@ private: ...@@ -289,43 +397,45 @@ private:
// The list of value IDs (in the order found) of defining function // The list of value IDs (in the order found) of defining function
// addresses. // addresses.
std::vector<unsigned> DefiningFunctionsList; std::vector<unsigned> DefiningFunctionsList;
// Error recovery value to use when getFuncSigTypeByID fails.
Ice::FuncSigType UndefinedFuncSigType;
bool ParseBlock(unsigned BlockID) override; bool ParseBlock(unsigned BlockID) override;
/// Reports that type ID is undefined, and then returns // Gets extended type associated with the given index, assuming the
/// the void type. // extended type is of the WantedKind. Generates error message if
Type *reportTypeIDAsUndefined(unsigned ID); // corresponding extended type of WantedKind can't be found, and
// returns nullptr.
ExtendedType *getTypeByIDAsKind(unsigned ID,
ExtendedType::TypeKind WantedKind) {
ExtendedType *Ty = nullptr;
if (ID < TypeIDValues.size()) {
Ty = &TypeIDValues[ID];
if (Ty->getKind() == WantedKind)
return Ty;
}
// Generate an error message and set ErrorStatus.
this->reportBadTypeIDAs(ID, Ty, WantedKind);
return nullptr;
}
/// Reports error about bad call to setTypeID. // Reports that type ID is undefined, or not of the WantedType.
void reportBadSetTypeID(unsigned ID, Type *Ty); void reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty,
ExtendedType::TypeKind WantedType);
// Reports that there is no corresponding ICE type for LLVMTy, and // Reports that there is no corresponding ICE type for LLVMTy, and
// returns ICE::IceType_void. // returns ICE::IceType_void.
Ice::Type convertToIceTypeError(Type *LLVMTy); Ice::Type convertToIceTypeError(Type *LLVMTy);
}; };
Type *TopLevelParser::reportTypeIDAsUndefined(unsigned ID) { void TopLevelParser::reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty,
std::string Buffer; ExtendedType::TypeKind WantedType) {
raw_string_ostream StrBuf(Buffer);
StrBuf << "Can't find type for type id: " << ID;
Error(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete.
Type *Ty = TypeConverter.convertToLLVMType(Ice::IceType_void);
// To reduce error messages, update type list if possible.
if (ID < TypeIDValues.size())
TypeIDValues[ID] = Ty;
return Ty;
}
void TopLevelParser::reportBadSetTypeID(unsigned ID, Type *Ty) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
if (ID >= TypeIDValues.size()) { if (Ty == nullptr) {
StrBuf << "Type index " << ID << " out of range: can't install."; StrBuf << "Can't find extended type for type id: " << ID;
} else { } else {
// Must be case that index already defined. StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty;
StrBuf << "Type index " << ID << " defined as " << *TypeIDValues[ID]
<< " and " << *Ty << ".";
} }
Error(StrBuf.str()); Error(StrBuf.str());
} }
...@@ -482,10 +592,13 @@ private: ...@@ -482,10 +592,13 @@ private:
unsigned NextTypeId; unsigned NextTypeId;
void ProcessRecord() override; void ProcessRecord() override;
void setNextTypeIDAsSimpleType(Ice::Type Ty) {
Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty);
}
}; };
void TypesParser::ProcessRecord() { void TypesParser::ProcessRecord() {
Type *Ty = nullptr;
const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
switch (Record.GetCode()) { switch (Record.GetCode()) {
case naclbitc::TYPE_CODE_NUMENTRY: case naclbitc::TYPE_CODE_NUMENTRY:
...@@ -498,71 +611,140 @@ void TypesParser::ProcessRecord() { ...@@ -498,71 +611,140 @@ void TypesParser::ProcessRecord() {
// VOID // VOID
if (!isValidRecordSize(0, "Type void")) if (!isValidRecordSize(0, "Type void"))
return; return;
Ty = Context->convertToLLVMType(Ice::IceType_void); setNextTypeIDAsSimpleType(Ice::IceType_void);
break; return;
case naclbitc::TYPE_CODE_FLOAT: case naclbitc::TYPE_CODE_FLOAT:
// FLOAT // FLOAT
if (!isValidRecordSize(0, "Type float")) if (!isValidRecordSize(0, "Type float"))
return; return;
Ty = Context->convertToLLVMType(Ice::IceType_f32); setNextTypeIDAsSimpleType(Ice::IceType_f32);
break; return;
case naclbitc::TYPE_CODE_DOUBLE: case naclbitc::TYPE_CODE_DOUBLE:
// DOUBLE // DOUBLE
if (!isValidRecordSize(0, "Type double")) if (!isValidRecordSize(0, "Type double"))
return; return;
Ty = Context->convertToLLVMType(Ice::IceType_f64); setNextTypeIDAsSimpleType(Ice::IceType_f64);
break; return;
case naclbitc::TYPE_CODE_INTEGER: case naclbitc::TYPE_CODE_INTEGER:
// INTEGER: [width] // INTEGER: [width]
if (!isValidRecordSize(1, "Type integer")) if (!isValidRecordSize(1, "Type integer"))
return; return;
Ty = Context->getLLVMIntegerType(Values[0]); switch (Values[0]) {
if (Ty == nullptr) { case 1:
setNextTypeIDAsSimpleType(Ice::IceType_i1);
return;
case 8:
setNextTypeIDAsSimpleType(Ice::IceType_i8);
return;
case 16:
setNextTypeIDAsSimpleType(Ice::IceType_i16);
return;
case 32:
setNextTypeIDAsSimpleType(Ice::IceType_i32);
return;
case 64:
setNextTypeIDAsSimpleType(Ice::IceType_i64);
return;
default:
break;
}
{
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Type integer record with invalid bitsize: " << Values[0]; StrBuf << "Type integer record with invalid bitsize: " << Values[0];
Error(StrBuf.str()); Error(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete.
// Fix type so that we can continue.
Ty = Context->convertToLLVMType(Ice::IceType_i32);
} }
break; return;
case naclbitc::TYPE_CODE_VECTOR: { case naclbitc::TYPE_CODE_VECTOR: {
// VECTOR: [numelts, eltty] // VECTOR: [numelts, eltty]
if (!isValidRecordSize(2, "Type vector")) if (!isValidRecordSize(2, "Type vector"))
return; return;
Type *BaseTy = Context->getTypeByID(Values[1]); Ice::Type BaseTy = Context->getSimpleTypeByID(Values[1]);
Ty = Context->getLLVMVectorType(Values[0], Ice::SizeT Size = Values[0];
Context->convertToIceType(BaseTy)); switch (BaseTy) {
if (Ty == nullptr) { case Ice::IceType_i1:
switch (Size) {
case 4:
setNextTypeIDAsSimpleType(Ice::IceType_v4i1);
return;
case 8:
setNextTypeIDAsSimpleType(Ice::IceType_v8i1);
return;
case 16:
setNextTypeIDAsSimpleType(Ice::IceType_v16i1);
return;
default:
break;
}
break;
case Ice::IceType_i8:
if (Size == 16) {
setNextTypeIDAsSimpleType(Ice::IceType_v16i8);
return;
}
break;
case Ice::IceType_i16:
if (Size == 8) {
setNextTypeIDAsSimpleType(Ice::IceType_v8i16);
return;
}
break;
case Ice::IceType_i32:
if (Size == 4) {
setNextTypeIDAsSimpleType(Ice::IceType_v4i32);
return;
}
break;
case Ice::IceType_f32:
if (Size == 4) {
setNextTypeIDAsSimpleType(Ice::IceType_v4f32);
return;
}
break;
default:
break;
}
{
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Invalid type vector record: <" << Values[0] << " x " << *BaseTy StrBuf << "Invalid type vector record: <" << Values[0] << " x " << BaseTy
<< ">"; << ">";
Error(StrBuf.str()); Error(StrBuf.str());
Ty = Context->convertToLLVMType(Ice::IceType_void);
} }
break; return;
} }
case naclbitc::TYPE_CODE_FUNCTION: { case naclbitc::TYPE_CODE_FUNCTION: {
// FUNCTION: [vararg, retty, paramty x N] // FUNCTION: [vararg, retty, paramty x N]
if (!isValidRecordSizeAtLeast(2, "Type signature")) if (!isValidRecordSizeAtLeast(2, "Type signature"))
return; return;
SmallVector<Type *, 8> ArgTys; if (Values[0])
Error("Function type can't define varargs");
ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++);
Ty->setAsFunctionType();
FuncSigExtendedType *FuncTy = cast<FuncSigExtendedType>(Ty);
FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1]));
for (unsigned i = 2, e = Values.size(); i != e; ++i) { for (unsigned i = 2, e = Values.size(); i != e; ++i) {
ArgTys.push_back(Context->getTypeByID(Values[i])); // Check that type void not used as argument type.
// Note: PNaCl restrictions can't be checked until we
// know the name, because we have to check for intrinsic signatures.
Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]);
if (ArgTy == Ice::IceType_void) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Type for parameter " << (i - 1)
<< " not valid. Found: " << ArgTy;
// TODO(kschimpf) Remove error recovery once implementation complete.
ArgTy = Ice::IceType_i32;
} }
Ty = FunctionType::get(Context->getTypeByID(Values[1]), ArgTys, Values[0]); FuncTy->appendArgType(ArgTy);
break; }
return;
} }
default: default:
BlockParserBaseClass::ProcessRecord(); BlockParserBaseClass::ProcessRecord();
return; return;
} }
// If Ty not defined, assume error. Use void as filler. llvm_unreachable("Unknown type block record not processed!");
if (Ty == nullptr)
Ty = Context->convertToLLVMType(Ice::IceType_void);
Context->setTypeID(NextTypeId++, Ty);
} }
/// Parses the globals block (i.e. global variables). /// Parses the globals block (i.e. global variables).
...@@ -1427,7 +1609,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1427,7 +1609,7 @@ void FunctionParser::ProcessRecord() {
if (!isValidRecordSize(3, "function block cast")) if (!isValidRecordSize(3, "function block cast"))
return; return;
Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
Type *CastType = Context->getTypeByID(Values[1]); Ice::Type CastType = Context->getSimpleTypeByID(Values[1]);
Instruction::CastOps LLVMCastOp; Instruction::CastOps LLVMCastOp;
Ice::InstCast::OpKind CastKind; Ice::InstCast::OpKind CastKind;
if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) || if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) ||
...@@ -1438,18 +1620,18 @@ void FunctionParser::ProcessRecord() { ...@@ -1438,18 +1620,18 @@ void FunctionParser::ProcessRecord() {
Error(StrBuf.str()); Error(StrBuf.str());
return; return;
} }
Type *SrcType = Context->convertToLLVMType(Src->getType()); Ice::Type SrcType = Src->getType();
if (!CastInst::castIsValid(LLVMCastOp, SrcType, CastType)) { if (!CastInst::castIsValid(LLVMCastOp, Context->convertToLLVMType(SrcType),
Context->convertToLLVMType(CastType))) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp) StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp)
<< " " << *SrcType << " to " << *CastType; << " " << SrcType << " to " << CastType;
Error(StrBuf.str()); Error(StrBuf.str());
return; return;
} }
CurrentNode->appendInst(Ice::InstCast::create( CurrentNode->appendInst(
Func, CastKind, getNextInstVar(Context->convertToIceType(CastType)), Ice::InstCast::create(Func, CastKind, getNextInstVar(CastType), Src));
Src));
break; break;
} }
case naclbitc::FUNC_CODE_INST_VSELECT: { case naclbitc::FUNC_CODE_INST_VSELECT: {
...@@ -1669,8 +1851,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1669,8 +1851,7 @@ void FunctionParser::ProcessRecord() {
// already frozen when the problem was noticed. // already frozen when the problem was noticed.
if (!isValidRecordSizeAtLeast(4, "function block switch")) if (!isValidRecordSizeAtLeast(4, "function block switch"))
return; return;
Ice::Type CondTy = Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]);
Context->convertToIceType(Context->getTypeByID(Values[0]));
if (!Ice::isScalarIntegerType(CondTy)) { if (!Ice::isScalarIntegerType(CondTy)) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
...@@ -1738,7 +1919,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1738,7 +1919,7 @@ void FunctionParser::ProcessRecord() {
Error(StrBuf.str()); Error(StrBuf.str());
return; return;
} }
Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[0])); Ice::Type Ty = Context->getSimpleTypeByID(Values[0]);
if (Ty == Ice::IceType_void) { if (Ty == Ice::IceType_void) {
Error("Phi record using type void not allowed"); Error("Phi record using type void not allowed");
return; return;
...@@ -1789,7 +1970,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1789,7 +1970,7 @@ void FunctionParser::ProcessRecord() {
return; return;
unsigned Alignment; unsigned Alignment;
extractAlignment("Load", Values[1], Alignment); extractAlignment("Load", Values[1], Alignment);
Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[2])); Ice::Type Ty = Context->getSimpleTypeByID(Values[2]);
if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) if (!isValidLoadStoreAlignment(Alignment, Ty, "Load"))
return; return;
CurrentNode->appendInst( CurrentNode->appendInst(
...@@ -1881,7 +2062,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1881,7 +2062,7 @@ void FunctionParser::ProcessRecord() {
} }
} }
} else { } else {
ReturnType = Context->convertToIceType(Context->getTypeByID(Values[2])); ReturnType = Context->getSimpleTypeByID(Values[2]);
} }
// Create the call instruction. // Create the call instruction.
...@@ -1953,8 +2134,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1953,8 +2134,7 @@ void FunctionParser::ProcessRecord() {
// FORWARDTYPEREF: [opval, ty] // FORWARDTYPEREF: [opval, ty]
if (!isValidRecordSize(2, "function block forward type ref")) if (!isValidRecordSize(2, "function block forward type ref"))
return; return;
setOperand(Values[0], createInstVar(Context->convertToIceType( setOperand(Values[0], createInstVar(Context->getSimpleTypeByID(Values[1])));
Context->getTypeByID(Values[1]))));
break; break;
} }
default: default:
...@@ -2003,8 +2183,7 @@ void ConstantsParser::ProcessRecord() { ...@@ -2003,8 +2183,7 @@ void ConstantsParser::ProcessRecord() {
// SETTYPE: [typeid] // SETTYPE: [typeid]
if (!isValidRecordSize(1, "constants block set type")) if (!isValidRecordSize(1, "constants block set type"))
return; return;
NextConstantType = NextConstantType = Context->getSimpleTypeByID(Values[0]);
Context->convertToIceType(Context->getTypeByID(Values[0]));
if (NextConstantType == Ice::IceType_void) if (NextConstantType == Ice::IceType_void)
Error("constants block set type not allowed for void type"); Error("constants block set type not allowed for void type");
return; return;
...@@ -2298,15 +2477,7 @@ void ModuleParser::ProcessRecord() { ...@@ -2298,15 +2477,7 @@ void ModuleParser::ProcessRecord() {
// FUNCTION: [type, callingconv, isproto, linkage] // FUNCTION: [type, callingconv, isproto, linkage]
if (!isValidRecordSize(4, "Function heading")) if (!isValidRecordSize(4, "Function heading"))
return; return;
Type *Ty = Context->getTypeByID(Values[0]); const Ice::FuncSigType &Ty = Context->getFuncSigTypeByID(Values[0]);
FunctionType *FTy = dyn_cast<FunctionType>(Ty);
if (FTy == nullptr) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Function heading expects function type. Found: " << Ty;
Error(StrBuf.str());
return;
}
CallingConv::ID CallingConv; CallingConv::ID CallingConv;
if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) { if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
std::string Buffer; std::string Buffer;
...@@ -2324,7 +2495,14 @@ void ModuleParser::ProcessRecord() { ...@@ -2324,7 +2495,14 @@ void ModuleParser::ProcessRecord() {
Error(StrBuf.str()); Error(StrBuf.str());
return; return;
} }
Function *Func = Function::Create(FTy, Linkage, "", Context->getModule()); SmallVector<Type *, 8> ArgTys;
for (Ice::Type ArgType : Ty.getArgList()) {
ArgTys.push_back(Context->convertToLLVMType(ArgType));
}
Function *Func = Function::Create(
FunctionType::get(Context->convertToLLVMType(Ty.getReturnType()),
ArgTys, false),
Linkage, "", Context->getModule());
Func->setCallingConv(CallingConv); Func->setCallingConv(CallingConv);
if (Values[2] == 0) if (Values[2] == 0)
Context->setNextValueIDAsImplementedFunction(); Context->setNextValueIDAsImplementedFunction();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment