| Index: src/PNaClTranslator.cpp
|
| diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
|
| index 6642ba977bbc57b588503bfb6416e5bd02f14db8..4f7a745626bcad64bf6ee3cbaf5e7170d6c837f9 100644
|
| --- a/src/PNaClTranslator.cpp
|
| +++ b/src/PNaClTranslator.cpp
|
| @@ -24,7 +24,6 @@
|
| #include "llvm/Support/Format.h"
|
| #include "llvm/Support/MemoryBuffer.h"
|
| #include "llvm/Support/raw_ostream.h"
|
| -#include "llvm/Support/ValueHandle.h"
|
|
|
| #include "IceCfg.h"
|
| #include "IceCfgNode.h"
|
| @@ -36,9 +35,8 @@
|
| #include "IceTypeConverter.h"
|
| #include "PNaClTranslator.h"
|
|
|
| -using namespace llvm;
|
| -
|
| namespace {
|
| +using namespace llvm;
|
|
|
| // TODO(kschimpf) Remove error recovery once implementation complete.
|
| static cl::opt<bool> AllowErrorRecovery(
|
| @@ -160,19 +158,21 @@ class TopLevelParser : public NaClBitcodeParser {
|
| TopLevelParser &operator=(const TopLevelParser &) = delete;
|
|
|
| public:
|
| + typedef std::vector<Ice::FunctionDeclaration *> FunctionDeclarationListType;
|
| +
|
| TopLevelParser(Ice::Translator &Translator, const std::string &InputName,
|
| NaClBitcodeHeader &Header, NaClBitstreamCursor &Cursor,
|
| bool &ErrorStatus)
|
| : NaClBitcodeParser(Cursor), Translator(Translator),
|
| Mod(new Module(InputName, getGlobalContext())), DL(PNaClDataLayout),
|
| - Header(Header), TypeConverter(getLLVMContext()),
|
| + Header(Header), TypeConverter(Mod->getContext()),
|
| ErrorStatus(ErrorStatus), NumErrors(0), NumFunctionIds(0),
|
| NumFunctionBlocks(0) {
|
| Mod->setDataLayout(PNaClDataLayout);
|
| setErrStream(Translator.getContext()->getStrDump());
|
| }
|
|
|
| - ~TopLevelParser() override { DeleteContainerPointers(GlobalIDAddresses); }
|
| + ~TopLevelParser() override {}
|
|
|
| Ice::Translator &getTranslator() { return Translator; }
|
|
|
| @@ -198,9 +198,6 @@ public:
|
| /// Returns the number of bytes in the bitcode header.
|
| size_t getHeaderSize() const { return Header.getHeaderSize(); }
|
|
|
| - /// Returns the llvm context to use.
|
| - LLVMContext &getLLVMContext() const { return Mod->getContext(); }
|
| -
|
| /// Changes the size of the type list to the given size.
|
| void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); }
|
|
|
| @@ -236,36 +233,40 @@ public:
|
| }
|
|
|
| /// Sets the next function ID to the given LLVM function.
|
| - void setNextFunctionID(Function *Fcn) {
|
| + void setNextFunctionID(Ice::FunctionDeclaration *Fcn) {
|
| ++NumFunctionIds;
|
| - FunctionIDValues.push_back(Fcn);
|
| + FunctionDeclarationList.push_back(Fcn);
|
| }
|
|
|
| /// Defines the next function ID as one that has an implementation
|
| /// (i.e a corresponding function block in the bitcode).
|
| void setNextValueIDAsImplementedFunction() {
|
| - DefiningFunctionsList.push_back(FunctionIDValues.size());
|
| + DefiningFunctionDeclarationsList.push_back(FunctionDeclarationList.size());
|
| }
|
|
|
| /// Returns the value id that should be associated with the the
|
| /// current function block. Increments internal counters during call
|
| /// so that it will be in correct position for next function block.
|
| unsigned getNextFunctionBlockValueID() {
|
| - if (NumFunctionBlocks >= DefiningFunctionsList.size())
|
| + if (NumFunctionBlocks >= DefiningFunctionDeclarationsList.size())
|
| report_fatal_error(
|
| "More function blocks than defined function addresses");
|
| - return DefiningFunctionsList[NumFunctionBlocks++];
|
| + return DefiningFunctionDeclarationsList[NumFunctionBlocks++];
|
| }
|
|
|
| - /// Returns the LLVM Function address associated with ID.
|
| - Function *getFunctionByID(unsigned ID) const {
|
| - if (ID >= FunctionIDValues.size())
|
| - return nullptr;
|
| - Value *V = FunctionIDValues[ID];
|
| - return cast<Function>(V);
|
| + /// Returns the function associated with ID.
|
| + Ice::FunctionDeclaration *getFunctionByID(unsigned ID) {
|
| + if (ID < FunctionDeclarationList.size())
|
| + return FunctionDeclarationList[ID];
|
| + return reportGetFunctionByIDError(ID);
|
| }
|
|
|
| - /// Returns the corresponding constant associated with a global value
|
| + /// Returns the list of function declarations.
|
| + const FunctionDeclarationListType &getFunctionDeclarationList() const {
|
| + return FunctionDeclarationList;
|
| + }
|
| +
|
| + /// Returns the corresponding constant associated with a global declaration.
|
| /// (i.e. relocatable).
|
| Ice::Constant *getOrCreateGlobalConstantByID(unsigned ID) {
|
| // TODO(kschimpf): Can this be built when creating global initializers?
|
| @@ -273,7 +274,7 @@ public:
|
| if (ID >= ValueIDConstants.size()) {
|
| C = nullptr;
|
| unsigned ExpectedSize =
|
| - FunctionIDValues.size() + GlobalIDAddresses.size();
|
| + FunctionDeclarationList.size() + VariableDeclarations.size();
|
| if (ID >= ExpectedSize)
|
| ExpectedSize = ID;
|
| ValueIDConstants.resize(ExpectedSize);
|
| @@ -284,12 +285,13 @@ public:
|
| return C;
|
|
|
| // If reached, no such constant exists, create one.
|
| + // TODO(kschimpf) Don't get addresses of intrinsic function declarations.
|
| std::string Name;
|
| - unsigned FcnIDSize = FunctionIDValues.size();
|
| + unsigned FcnIDSize = FunctionDeclarationList.size();
|
| if (ID < FcnIDSize) {
|
| - Name = FunctionIDValues[ID]->getName();
|
| - } else if ((ID - FcnIDSize) < GlobalIDAddresses.size()) {
|
| - Name = GlobalIDAddresses[ID - FcnIDSize]->getName();
|
| + Name = FunctionDeclarationList[ID]->getName();
|
| + } else if ((ID - FcnIDSize) < VariableDeclarations.size()) {
|
| + Name = VariableDeclarations[ID - FcnIDSize]->getName();
|
| } else {
|
| std::string Buffer;
|
| raw_string_ostream StrBuf(Buffer);
|
| @@ -304,47 +306,49 @@ public:
|
| return C;
|
| }
|
|
|
| - /// Returns the number of function addresses (i.e. ID's) defined in
|
| - /// the bitcode file.
|
| + /// Returns the number of function declarations in the bitcode file.
|
| unsigned getNumFunctionIDs() const { return NumFunctionIds; }
|
|
|
| - /// Returns the number of global IDs (function and global addresses)
|
| - /// defined in the bitcode file.
|
| + /// Returns the number of global declarations (i.e. IDs) defined in
|
| + /// the bitcode file.
|
| unsigned getNumGlobalIDs() const {
|
| - return FunctionIDValues.size() + GlobalIDAddresses.size();
|
| + return FunctionDeclarationList.size() + VariableDeclarations.size();
|
| }
|
|
|
| - /// Creates Count global addresses.
|
| - void CreateGlobalAddresses(size_t Count) {
|
| - assert(GlobalIDAddresses.empty());
|
| + /// Creates Count global variable declarations.
|
| + void CreateGlobalVariables(size_t Count) {
|
| + assert(VariableDeclarations.empty());
|
| + Ice::GlobalContext *Context = getTranslator().getContext();
|
| for (size_t i = 0; i < Count; ++i) {
|
| - GlobalIDAddresses.push_back(new Ice::GlobalAddress());
|
| + VariableDeclarations.push_back(Ice::VariableDeclaration::create(Context));
|
| }
|
| }
|
|
|
| - /// Returns the number of global addresses (i.e. ID's) defined in
|
| - /// the bitcode file.
|
| - Ice::SizeT getNumGlobalAddresses() const { return GlobalIDAddresses.size(); }
|
| + /// Returns the number of global variable declarations in the
|
| + /// bitcode file.
|
| + Ice::SizeT getNumGlobalVariables() const {
|
| + return VariableDeclarations.size();
|
| + }
|
|
|
| - /// Returns the global address with the given index.
|
| - Ice::GlobalAddress *getGlobalAddress(size_t Index) {
|
| - if (Index < GlobalIDAddresses.size())
|
| - return GlobalIDAddresses[Index];
|
| - std::string Buffer;
|
| - raw_string_ostream StrBuf(Buffer);
|
| - StrBuf << "Global index " << Index
|
| - << " not allowed. Out of range. Must be less than "
|
| - << GlobalIDAddresses.size();
|
| - Error(StrBuf.str());
|
| - // TODO(kschimpf) Remove error recovery once implementation complete.
|
| - if (!GlobalIDAddresses.empty())
|
| - return GlobalIDAddresses[0];
|
| - report_fatal_error("Unable to continue");
|
| + /// Returns the global variable declaration with the given index.
|
| + Ice::VariableDeclaration *getGlobalVariableByID(unsigned Index) {
|
| + if (Index < VariableDeclarations.size())
|
| + return VariableDeclarations[Index];
|
| + return reportGetGlobalVariableByIDError(Index);
|
| + }
|
| +
|
| + /// Returns the global declaration (variable or function) with the
|
| + /// given Index.
|
| + Ice::GlobalDeclaration *getGlobalDeclarationByID(size_t Index) {
|
| + if (Index < NumFunctionIds)
|
| + return getFunctionByID(Index);
|
| + else
|
| + return getGlobalVariableByID(Index - NumFunctionIds);
|
| }
|
|
|
| - /// Returns the list of read global addresses.
|
| - const Ice::Translator::GlobalAddressList &getGlobalIDAddresses() {
|
| - return GlobalIDAddresses;
|
| + /// Returns the list of parsed global variable declarations.
|
| + const Ice::Translator::VariableDeclarationListType &getGlobalVariables() {
|
| + return VariableDeclarations;
|
| }
|
|
|
| /// Returns the corresponding ICE type for LLVMTy.
|
| @@ -383,20 +387,21 @@ private:
|
| unsigned NumErrors;
|
| // The types associated with each type ID.
|
| std::vector<ExtendedType> TypeIDValues;
|
| - // The set of function value IDs.
|
| - std::vector<WeakVH> FunctionIDValues;
|
| - // The set of global addresses IDs.
|
| - Ice::Translator::GlobalAddressList GlobalIDAddresses;
|
| - // Relocatable constants associated with FunctionIDValues and
|
| - // GlobalIDAddresses.
|
| + // The set of functions.
|
| + FunctionDeclarationListType FunctionDeclarationList;
|
| + // The set of global variables.
|
| + Ice::Translator::VariableDeclarationListType VariableDeclarations;
|
| + // Relocatable constants associated with global declarations.
|
| std::vector<Ice::Constant *> ValueIDConstants;
|
| - // The number of function IDs.
|
| + // The number of function declarations (i.e. IDs).
|
| unsigned NumFunctionIds;
|
| // The number of function blocks (processed so far).
|
| unsigned NumFunctionBlocks;
|
| - // The list of value IDs (in the order found) of defining function
|
| - // addresses.
|
| - std::vector<unsigned> DefiningFunctionsList;
|
| + // The list of function declaration IDs (in the order found) that
|
| + // aren't just proto declarations.
|
| + // TODO(kschimpf): Instead of using this list, just use
|
| + // FunctionDeclarationList, and the isProto member function.
|
| + std::vector<unsigned> DefiningFunctionDeclarationsList;
|
| // Error recovery value to use when getFuncSigTypeByID fails.
|
| Ice::FuncSigType UndefinedFuncSigType;
|
|
|
| @@ -423,6 +428,14 @@ private:
|
| void reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty,
|
| ExtendedType::TypeKind WantedType);
|
|
|
| + // Reports that there is no function declaration for ID. Returns an
|
| + // error recovery value to use.
|
| + Ice::FunctionDeclaration *reportGetFunctionByIDError(unsigned ID);
|
| +
|
| + // Reports that there is not global variable declaration for
|
| + // ID. Returns an error recovery value to use.
|
| + Ice::VariableDeclaration *reportGetGlobalVariableByIDError(unsigned Index);
|
| +
|
| // Reports that there is no corresponding ICE type for LLVMTy, and
|
| // returns ICE::IceType_void.
|
| Ice::Type convertToIceTypeError(Type *LLVMTy);
|
| @@ -440,6 +453,34 @@ void TopLevelParser::reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty,
|
| Error(StrBuf.str());
|
| }
|
|
|
| +Ice::FunctionDeclaration *
|
| +TopLevelParser::reportGetFunctionByIDError(unsigned ID) {
|
| + std::string Buffer;
|
| + raw_string_ostream StrBuf(Buffer);
|
| + StrBuf << "Function index " << ID
|
| + << " not allowed. Out of range. Must be less than "
|
| + << FunctionDeclarationList.size();
|
| + Error(StrBuf.str());
|
| + // TODO(kschimpf) Remove error recovery once implementation complete.
|
| + if (!FunctionDeclarationList.empty())
|
| + return FunctionDeclarationList[0];
|
| + report_fatal_error("Unable to continue");
|
| +}
|
| +
|
| +Ice::VariableDeclaration *
|
| +TopLevelParser::reportGetGlobalVariableByIDError(unsigned Index) {
|
| + std::string Buffer;
|
| + raw_string_ostream StrBuf(Buffer);
|
| + StrBuf << "Global index " << Index
|
| + << " not allowed. Out of range. Must be less than "
|
| + << VariableDeclarations.size();
|
| + Error(StrBuf.str());
|
| + // TODO(kschimpf) Remove error recovery once implementation complete.
|
| + if (!VariableDeclarations.empty())
|
| + return VariableDeclarations[0];
|
| + report_fatal_error("Unable to continue");
|
| +}
|
| +
|
| Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) {
|
| std::string Buffer;
|
| raw_string_ostream StrBuf(Buffer);
|
| @@ -747,38 +788,40 @@ void TypesParser::ProcessRecord() {
|
| llvm_unreachable("Unknown type block record not processed!");
|
| }
|
|
|
| -/// Parses the globals block (i.e. global variables).
|
| +/// Parses the globals block (i.e. global variable declarations and
|
| +/// corresponding initializers).
|
| class GlobalsParser : public BlockParserBaseClass {
|
| public:
|
| GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
|
| : BlockParserBaseClass(BlockID, EnclosingParser), InitializersNeeded(0),
|
| - NextGlobalID(0), CurrentAddress(&DummyAddress) {}
|
| -
|
| - ~GlobalsParser() override {}
|
| + NextGlobalID(0), DummyGlobalVar(Ice::VariableDeclaration::create(
|
| + getTranslator().getContext())),
|
| + CurGlobalVar(DummyGlobalVar) {}
|
|
|
| private:
|
| // Keeps track of how many initializers are expected for the global variable
|
| - // being built.
|
| + // declaration being built.
|
| unsigned InitializersNeeded;
|
|
|
| - // The index of the next global variable.
|
| + // The index of the next global variable declaration.
|
| unsigned NextGlobalID;
|
|
|
| - // Holds the current global address whose initializer is being defined.
|
| - Ice::GlobalAddress *CurrentAddress;
|
| + // Dummy global variable declaration to guarantee CurGlobalVar is
|
| + // always defined (allowing code to not need to check if
|
| + // CurGlobalVar is nullptr).
|
| + Ice::VariableDeclaration *DummyGlobalVar;
|
|
|
| - // Dummy global address to guarantee CurrentAddress is always defined
|
| - // (allowing code to not need to check if CurrentAddress is nullptr).
|
| - Ice::GlobalAddress DummyAddress;
|
| + // Holds the current global variable declaration being built.
|
| + Ice::VariableDeclaration *CurGlobalVar;
|
|
|
| void ExitBlock() override {
|
| verifyNoMissingInitializers();
|
| - unsigned NumIDs = Context->getNumGlobalAddresses();
|
| + unsigned NumIDs = Context->getNumGlobalVariables();
|
| if (NextGlobalID < NumIDs) {
|
| std::string Buffer;
|
| raw_string_ostream StrBuf(Buffer);
|
| StrBuf << "Globals block expects " << NumIDs
|
| - << " global definitions. Found: " << NextGlobalID;
|
| + << " global variable declarations. Found: " << NextGlobalID;
|
| Error(StrBuf.str());
|
| }
|
| BlockParserBaseClass::ExitBlock();
|
| @@ -786,12 +829,12 @@ private:
|
|
|
| void ProcessRecord() override;
|
|
|
| - // Checks if the number of initializers for the CurrentAddress is the same as
|
| + // Checks if the number of initializers for the CurGlobalVar is the same as
|
| // the number found in the bitcode file. If different, and error message is
|
| // generated, and the internal state of the parser is fixed so this condition
|
| // is no longer violated.
|
| void verifyNoMissingInitializers() {
|
| - size_t NumInits = CurrentAddress->getInitializers().size();
|
| + size_t NumInits = CurGlobalVar->getInitializers().size();
|
| if (InitializersNeeded != NumInits) {
|
| std::string Buffer;
|
| raw_string_ostream StrBuf(Buffer);
|
| @@ -801,6 +844,7 @@ private:
|
| StrBuf << "s";
|
| StrBuf << ". Found: " << NumInits;
|
| Error(StrBuf.str());
|
| + InitializersNeeded = NumInits;
|
| }
|
| }
|
| };
|
| @@ -812,11 +856,11 @@ void GlobalsParser::ProcessRecord() {
|
| // COUNT: [n]
|
| if (!isValidRecordSize(1, "Globals count"))
|
| return;
|
| - if (NextGlobalID != Context->getNumGlobalAddresses()) {
|
| + if (NextGlobalID != Context->getNumGlobalVariables()) {
|
| Error("Globals count record not first in block.");
|
| return;
|
| }
|
| - Context->CreateGlobalAddresses(Values[0]);
|
| + Context->CreateGlobalVariables(Values[0]);
|
| return;
|
| case naclbitc::GLOBALVAR_VAR: {
|
| // VAR: [align, isconst]
|
| @@ -824,9 +868,9 @@ void GlobalsParser::ProcessRecord() {
|
| return;
|
| verifyNoMissingInitializers();
|
| InitializersNeeded = 1;
|
| - CurrentAddress = Context->getGlobalAddress(NextGlobalID);
|
| - CurrentAddress->setAlignment((1 << Values[0]) >> 1);
|
| - CurrentAddress->setIsConstant(Values[1] != 0);
|
| + CurGlobalVar = Context->getGlobalVariableByID(NextGlobalID);
|
| + CurGlobalVar->setAlignment((1 << Values[0]) >> 1);
|
| + CurGlobalVar->setIsConstant(Values[1] != 0);
|
| ++NextGlobalID;
|
| return;
|
| }
|
| @@ -834,7 +878,7 @@ void GlobalsParser::ProcessRecord() {
|
| // COMPOUND: [size]
|
| if (!isValidRecordSize(1, "globals compound"))
|
| return;
|
| - if (!CurrentAddress->getInitializers().empty()) {
|
| + if (!CurGlobalVar->getInitializers().empty()) {
|
| Error("Globals compound record not first initializer");
|
| return;
|
| }
|
| @@ -851,17 +895,17 @@ void GlobalsParser::ProcessRecord() {
|
| // ZEROFILL: [size]
|
| if (!isValidRecordSize(1, "Globals zerofill"))
|
| return;
|
| - CurrentAddress->addInitializer(
|
| - new Ice::GlobalAddress::ZeroInitializer(Values[0]));
|
| - break;
|
| + CurGlobalVar->addInitializer(
|
| + new Ice::VariableDeclaration::ZeroInitializer(Values[0]));
|
| + return;
|
| }
|
| case naclbitc::GLOBALVAR_DATA: {
|
| // DATA: [b0, b1, ...]
|
| if (!isValidRecordSizeAtLeast(1, "Globals data"))
|
| return;
|
| - CurrentAddress->addInitializer(
|
| - new Ice::GlobalAddress::DataInitializer(Values));
|
| - break;
|
| + CurGlobalVar->addInitializer(
|
| + new Ice::VariableDeclaration::DataInitializer(Values));
|
| + return;
|
| }
|
| case naclbitc::GLOBALVAR_RELOC: {
|
| // RELOC: [val, [addend]]
|
| @@ -871,19 +915,9 @@ void GlobalsParser::ProcessRecord() {
|
| Ice::SizeT Offset = 0;
|
| if (Values.size() == 2)
|
| Offset = Values[1];
|
| - unsigned NumFunctions = Context->getNumFunctionIDs();
|
| - if (Index < NumFunctions) {
|
| - llvm::Function *Fcn = Context->getFunctionByID(Index);
|
| - Ice::GlobalAddress::RelocationAddress Addr(Fcn);
|
| - CurrentAddress->addInitializer(
|
| - new Ice::GlobalAddress::RelocInitializer(Addr, Offset));
|
| - } else {
|
| - Ice::GlobalAddress::RelocationAddress Addr(
|
| - Context->getGlobalAddress(Index - NumFunctions));
|
| - CurrentAddress->addInitializer(
|
| - new Ice::GlobalAddress::RelocInitializer(Addr, Offset));
|
| - }
|
| - break;
|
| + CurGlobalVar->addInitializer(new Ice::VariableDeclaration::RelocInitializer(
|
| + Context->getGlobalDeclarationByID(Index), Offset));
|
| + return;
|
| }
|
| default:
|
| BlockParserBaseClass::ProcessRecord();
|
| @@ -964,23 +998,25 @@ public:
|
| : BlockParserBaseClass(BlockID, EnclosingParser),
|
| Func(new Ice::Cfg(getTranslator().getContext())), CurrentBbIndex(0),
|
| FcnId(Context->getNextFunctionBlockValueID()),
|
| - LLVMFunc(Context->getFunctionByID(FcnId)),
|
| + FuncDecl(Context->getFunctionByID(FcnId)),
|
| CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
|
| NextLocalInstIndex(Context->getNumGlobalIDs()),
|
| InstIsTerminating(false) {
|
| - Func->setFunctionName(LLVMFunc->getName());
|
| + Func->setFunctionName(FuncDecl->getName());
|
| if (getFlags().TimeEachFunction)
|
| getTranslator().getContext()->pushTimer(
|
| getTranslator().getContext()->getTimerID(
|
| Ice::GlobalContext::TSK_Funcs, Func->getFunctionName()),
|
| Ice::GlobalContext::TSK_Funcs);
|
| - Func->setReturnType(Context->convertToIceType(LLVMFunc->getReturnType()));
|
| - Func->setInternal(LLVMFunc->hasInternalLinkage());
|
| + // TODO(kschimpf) Clean up API to add a function signature to
|
| + // a CFG.
|
| + const Ice::FuncSigType &Signature = FuncDecl->getSignature();
|
| + Func->setReturnType(Signature.getReturnType());
|
| + Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage);
|
| CurrentNode = InstallNextBasicBlock();
|
| Func->setEntryNode(CurrentNode);
|
| - for (auto ArgI = LLVMFunc->arg_begin(), ArgE = LLVMFunc->arg_end();
|
| - ArgI != ArgE; ++ArgI) {
|
| - Func->addArg(getNextInstVar(Context->convertToIceType(ArgI->getType())));
|
| + for (Ice::Type ArgType : Signature.getArgList()) {
|
| + Func->addArg(getNextInstVar(ArgType));
|
| }
|
| }
|
|
|
| @@ -1000,8 +1036,8 @@ private:
|
| Ice::CfgNode *CurrentNode;
|
| // The ID for the function.
|
| unsigned FcnId;
|
| - // The corresponding LLVM function.
|
| - Function *LLVMFunc;
|
| + // The corresponding function declaration.
|
| + Ice::FunctionDeclaration *FuncDecl;
|
| // Holds the dividing point between local and global absolute value indices.
|
| uint32_t CachedNumGlobalValueIDs;
|
| // Holds operands local to the function block, based on indices
|
| @@ -1999,12 +2035,12 @@ void FunctionParser::ProcessRecord() {
|
| // CALL_INDIRECT: [cc, fn, returnty, args...]
|
| //
|
| // Note: The difference between CALL and CALL_INDIRECT is that
|
| - // CALL has an explicit function address, while the CALL_INDIRECT
|
| - // is just an address. For CALL, we can infer the return type by
|
| - // looking up the type signature associated with the function
|
| - // address. For CALL_INDIRECT we can only infer the type signature
|
| - // via argument types, and the corresponding return type stored in
|
| - // CALL_INDIRECT record.
|
| + // CALL has a reference to an explicit function declaration, while
|
| + // the CALL_INDIRECT is just an address. For CALL, we can infer
|
| + // the return type by looking up the type signature associated
|
| + // with the function declaration. For CALL_INDIRECT we can only
|
| + // infer the type signature via argument types, and the
|
| + // corresponding return type stored in CALL_INDIRECT record.
|
| Ice::SizeT ParamsStartIndex = 2;
|
| if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
|
| if (!isValidRecordSizeAtLeast(2, "function block call"))
|
| @@ -2034,17 +2070,9 @@ void FunctionParser::ProcessRecord() {
|
| Ice::Type ReturnType = Ice::IceType_void;
|
| const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr;
|
| if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
|
| - Function *Fcn = Context->getFunctionByID(CalleeIndex);
|
| - if (Fcn == nullptr) {
|
| - std::string Buffer;
|
| - raw_string_ostream StrBuf(Buffer);
|
| - StrBuf << "Function call to non-function: " << *Callee;
|
| - Error(StrBuf.str());
|
| - return;
|
| - }
|
| -
|
| - FunctionType *FcnTy = Fcn->getFunctionType();
|
| - ReturnType = Context->convertToIceType(FcnTy->getReturnType());
|
| + Ice::FunctionDeclaration *Fcn = Context->getFunctionByID(CalleeIndex);
|
| + const Ice::FuncSigType &Signature = Fcn->getSignature();
|
| + ReturnType = Signature.getReturnType();
|
|
|
| // Check if this direct call is to an Intrinsic (starts with "llvm.")
|
| static Ice::IceString LLVMPrefix("llvm.");
|
| @@ -2339,45 +2367,60 @@ class ModuleParser : public BlockParserBaseClass {
|
| public:
|
| ModuleParser(unsigned BlockID, TopLevelParser *Context)
|
| : BlockParserBaseClass(BlockID, Context),
|
| - GlobalAddressNamesAndInitializersInstalled(false) {}
|
| + GlobalDeclarationNamesAndInitializersInstalled(false) {}
|
|
|
| ~ModuleParser() override {}
|
|
|
| private:
|
| - // True if we have already instaledl names for unnamed global addresses,
|
| - // and generated global constant initializers.
|
| - bool GlobalAddressNamesAndInitializersInstalled;
|
| -
|
| - // Generates names for unnamed global addresses, and lowers global
|
| - // constant initializers to the target. May be called multiple
|
| - // times. Only the first call will do the installation.
|
| - void InstallGlobalAddressNamesAndInitializers() {
|
| - if (!GlobalAddressNamesAndInitializersInstalled) {
|
| + // True if we have already installed names for unnamed global declarations,
|
| + // and have generated global constant initializers.
|
| + bool GlobalDeclarationNamesAndInitializersInstalled;
|
| +
|
| + // Generates names for unnamed global addresses (i.e. functions and
|
| + // global variables). Then lowers global variable declaration
|
| + // initializers to the target. May be called multiple times. Only
|
| + // the first call will do the installation.
|
| + void InstallGlobalNamesAndGlobalVarInitializers() {
|
| + if (!GlobalDeclarationNamesAndInitializersInstalled) {
|
| Ice::Translator &Trans = getTranslator();
|
| const Ice::IceString &GlobalPrefix = getFlags().DefaultGlobalPrefix;
|
| if (!GlobalPrefix.empty()) {
|
| uint32_t NameIndex = 0;
|
| - for (Ice::GlobalAddress *Address : Context->getGlobalIDAddresses()) {
|
| - if (!Address->hasName()) {
|
| - Address->setName(Trans.createUnnamedName(GlobalPrefix, NameIndex));
|
| - ++NameIndex;
|
| - } else {
|
| - Trans.checkIfUnnamedNameSafe(Address->getName(), "global",
|
| - GlobalPrefix,
|
| - Trans.getContext()->getStrDump());
|
| - }
|
| + for (Ice::VariableDeclaration *Var : Context->getGlobalVariables()) {
|
| + installDeclarationName(Trans, Var, GlobalPrefix, "global", NameIndex);
|
| + }
|
| + }
|
| + const Ice::IceString &FunctionPrefix = getFlags().DefaultFunctionPrefix;
|
| + if (!FunctionPrefix.empty()) {
|
| + uint32_t NameIndex = 0;
|
| + for (Ice::FunctionDeclaration *Func :
|
| + Context->getFunctionDeclarationList()) {
|
| + installDeclarationName(Trans, Func, FunctionPrefix, "function",
|
| + NameIndex);
|
| }
|
| }
|
| - Trans.nameUnnamedFunctions(Context->getModule());
|
| - getTranslator().lowerGlobals(Context->getGlobalIDAddresses());
|
| - GlobalAddressNamesAndInitializersInstalled = true;
|
| + getTranslator().lowerGlobals(Context->getGlobalVariables());
|
| + GlobalDeclarationNamesAndInitializersInstalled = true;
|
| + }
|
| + }
|
| +
|
| + void installDeclarationName(Ice::Translator &Trans,
|
| + Ice::GlobalDeclaration *Decl,
|
| + const Ice::IceString &Prefix, const char *Context,
|
| + uint32_t &NameIndex) {
|
| + if (!Decl->hasName()) {
|
| + Decl->setName(Trans.createUnnamedName(Prefix, NameIndex));
|
| + ++NameIndex;
|
| + } else {
|
| + Trans.checkIfUnnamedNameSafe(Decl->getName(), Context, Prefix,
|
| + Trans.getContext()->getStrDump());
|
| }
|
| }
|
|
|
| bool ParseBlock(unsigned BlockID) override;
|
|
|
| void ExitBlock() override {
|
| - InstallGlobalAddressNamesAndInitializers();
|
| + InstallGlobalNamesAndGlobalVarInitializers();
|
| getTranslator().emitConstants();
|
| }
|
|
|
| @@ -2400,26 +2443,8 @@ private:
|
| };
|
|
|
| void ModuleValuesymtabParser::setValueName(uint64_t Index, StringType &Name) {
|
| - if (Index < Context->getNumFunctionIDs()) {
|
| - Function *Fcn = Context->getFunctionByID(Index);
|
| - if (Fcn != nullptr) {
|
| - Fcn->setName(StringRef(Name.data(), Name.size()));
|
| - return;
|
| - }
|
| - } else {
|
| - unsigned NumFunctions = Context->getNumFunctionIDs();
|
| - if (Index >= NumFunctions) {
|
| - Context->getGlobalAddress(Index - NumFunctions)
|
| - ->setName(StringRef(Name.data(), Name.size()));
|
| - }
|
| - return;
|
| - }
|
| -
|
| - std::string Buffer;
|
| - raw_string_ostream StrBuf(Buffer);
|
| - StrBuf << "Invalid global address ID in valuesymtab: " << Index;
|
| - Error(StrBuf.str());
|
| - return;
|
| + Context->getGlobalDeclarationByID(Index)
|
| + ->setName(StringRef(Name.data(), Name.size()));
|
| }
|
|
|
| void ModuleValuesymtabParser::setBbName(uint64_t Index, StringType &Name) {
|
| @@ -2447,7 +2472,7 @@ bool ModuleParser::ParseBlock(unsigned BlockID) {
|
| return Parser.ParseThisBlock();
|
| }
|
| case naclbitc::FUNCTION_BLOCK_ID: {
|
| - InstallGlobalAddressNamesAndInitializers();
|
| + InstallGlobalNamesAndGlobalVarInitializers();
|
| FunctionParser Parser(BlockID, this);
|
| return Parser.ParseThisBlock();
|
| }
|
| @@ -2476,7 +2501,7 @@ void ModuleParser::ProcessRecord() {
|
| // FUNCTION: [type, callingconv, isproto, linkage]
|
| if (!isValidRecordSize(4, "Function heading"))
|
| return;
|
| - const Ice::FuncSigType &Ty = Context->getFuncSigTypeByID(Values[0]);
|
| + const Ice::FuncSigType &Signature = Context->getFuncSigTypeByID(Values[0]);
|
| CallingConv::ID CallingConv;
|
| if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
|
| std::string Buffer;
|
| @@ -2494,19 +2519,12 @@ void ModuleParser::ProcessRecord() {
|
| Error(StrBuf.str());
|
| return;
|
| }
|
| - 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);
|
| + Ice::FunctionDeclaration *Func = Ice::FunctionDeclaration::create(
|
| + getTranslator().getContext(), Signature, CallingConv, Linkage,
|
| + Values[2] == 0);
|
| if (Values[2] == 0)
|
| Context->setNextValueIDAsImplementedFunction();
|
| Context->setNextFunctionID(Func);
|
| - // TODO(kschimpf) verify if Func matches PNaCl ABI.
|
| return;
|
| }
|
| default:
|
|
|