Chromium Code Reviews| Index: src/PNaClTranslator.cpp |
| diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp |
| index 46bd26159e906f80af701e7e97807c723cd0c71f..453b3bf2400df4d0b493f38cf0765d4c5e198d97 100644 |
| --- a/src/PNaClTranslator.cpp |
| +++ b/src/PNaClTranslator.cpp |
| @@ -163,6 +163,7 @@ public: |
| NaClBitstreamCursor &Cursor, Ice::ErrorCode &ErrorStatus) |
| : NaClBitcodeParser(Cursor), Translator(Translator), Header(Header), |
| ErrorStatus(ErrorStatus), NumErrors(0), NextDefiningFunctionID(0), |
| + VariableDeclarations(new Ice::VariableDeclarationList()), |
| BlockParser(nullptr), StubbedConstCallValue(nullptr) {} |
| ~TopLevelParser() override {} |
| @@ -251,71 +252,27 @@ public: |
| return reportGetFunctionByIDError(ID); |
| } |
| - /// Returns the list of function declarations. |
| - const FunctionDeclarationListType &getFunctionDeclarationList() const { |
| - return FunctionDeclarationList; |
| + /// Returns the constant associated with the given global value ID. |
| + Ice::Constant *getGlobalConstantByID(unsigned ID) { |
| + assert(ID < ValueIDConstants.size()); |
| + return ValueIDConstants[ID]; |
| } |
| - /// 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? |
| - Ice::Constant *C; |
| - if (ID >= ValueIDConstants.size()) { |
| - C = nullptr; |
| - unsigned ExpectedSize = |
| - FunctionDeclarationList.size() + VariableDeclarations.size(); |
| - if (ID >= ExpectedSize) |
| - ExpectedSize = ID; |
| - ValueIDConstants.resize(ExpectedSize); |
| - } else { |
| - C = ValueIDConstants[ID]; |
| - } |
| - if (C != nullptr) |
| - return C; |
| + /// Install names for all global values without names. Called after |
| + /// the global value symbol table is processed, but before any |
| + /// function blocks are processed. |
| + void installGlobalNames() { |
| + assert(VariableDeclarations); |
| + installGlobalVarNames(); |
| + installFunctionNames(); |
| + } |
| - if (isIRGenerationDisabled()) { |
| - ValueIDConstants[ID] = nullptr; |
| - return nullptr; |
| - } |
| - |
| - // If reached, no such constant exists, create one. |
| - // TODO(kschimpf) Don't get addresses of intrinsic function declarations. |
| - Ice::GlobalDeclaration *Decl = nullptr; |
| - unsigned FcnIDSize = FunctionDeclarationList.size(); |
| - bool IsUndefined = false; |
| - if (ID < FcnIDSize) { |
| - Decl = FunctionDeclarationList[ID]; |
| - const auto Func = llvm::cast<Ice::FunctionDeclaration>(Decl); |
| - IsUndefined = Func->isProto(); |
| - } else if ((ID - FcnIDSize) < VariableDeclarations.size()) { |
| - Decl = VariableDeclarations[ID - FcnIDSize]; |
| - const auto Var = llvm::cast<Ice::VariableDeclaration>(Decl); |
| - IsUndefined = !Var->hasInitializer(); |
| - } |
| - Ice::IceString Name; |
| - bool SuppressMangling; |
| - if (Decl) { |
| - Name = Decl->getName(); |
| - SuppressMangling = Decl->getSuppressMangling(); |
| - } else { |
| - std::string Buffer; |
| - raw_string_ostream StrBuf(Buffer); |
| - StrBuf << "Reference to global not defined: " << ID; |
| - BlockError(StrBuf.str()); |
| - // TODO(kschimpf) Remove error recovery once implementation complete. |
| - Name = "??"; |
| - SuppressMangling = false; |
| - } |
| - if (IsUndefined) |
| - C = getTranslator().getContext()->getConstantExternSym(Name); |
| - else { |
| - const Ice::RelocOffsetT Offset = 0; |
| - C = getTranslator().getContext()->getConstantSym(Offset, Name, |
| - SuppressMangling); |
| - } |
| - ValueIDConstants[ID] = C; |
| - return C; |
| + void createValueIDs() { |
| + assert(VariableDeclarations); |
| + ValueIDConstants.reserve(VariableDeclarations->size() + |
| + FunctionDeclarationList.size()); |
| + createValueIDsForFunctions(); |
| + createValueIDsForGlobalVars(); |
| } |
| /// Returns a defined function reference to be used in place of |
| @@ -328,7 +285,7 @@ public: |
| for (unsigned i = 0; i < getNumFunctionIDs(); ++i) { |
| Ice::FunctionDeclaration *Func = getFunctionByID(i); |
| if (!Func->isProto()) { |
| - StubbedConstCallValue = getOrCreateGlobalConstantByID(i); |
| + StubbedConstCallValue = getGlobalConstantByID(i); |
| return StubbedConstCallValue; |
| } |
| } |
| @@ -342,27 +299,37 @@ public: |
| /// Returns the number of global declarations (i.e. IDs) defined in |
| /// the bitcode file. |
| unsigned getNumGlobalIDs() const { |
| - return FunctionDeclarationList.size() + VariableDeclarations.size(); |
| + if (VariableDeclarations) { |
| + return FunctionDeclarationList.size() + VariableDeclarations->size(); |
| + } else { |
| + return ValueIDConstants.size(); |
| + } |
| } |
| /// Creates Count global variable declarations. |
| void CreateGlobalVariables(size_t Count) { |
| - assert(VariableDeclarations.empty()); |
| + assert(VariableDeclarations); |
| + assert(VariableDeclarations->empty()); |
| for (size_t i = 0; i < Count; ++i) { |
| - VariableDeclarations.push_back(Ice::VariableDeclaration::create()); |
| + VariableDeclarations->push_back(Ice::VariableDeclaration::create()); |
| } |
| } |
| /// Returns the number of global variable declarations in the |
| /// bitcode file. |
| Ice::SizeT getNumGlobalVariables() const { |
| - return VariableDeclarations.size(); |
| + if (VariableDeclarations) { |
| + return VariableDeclarations->size(); |
| + } else { |
| + return ValueIDConstants.size() - FunctionDeclarationList.size(); |
| + } |
| } |
| /// Returns the global variable declaration with the given index. |
| Ice::VariableDeclaration *getGlobalVariableByID(unsigned Index) { |
| - if (Index < VariableDeclarations.size()) |
| - return VariableDeclarations[Index]; |
| + assert(VariableDeclarations); |
| + if (Index < VariableDeclarations->size()) |
| + return VariableDeclarations->at(Index); |
| return reportGetGlobalVariableByIDError(Index); |
| } |
| @@ -376,9 +343,14 @@ public: |
| return getGlobalVariableByID(Index - NumFunctionIds); |
| } |
| - /// Returns the list of parsed global variable declarations. |
| - const Ice::VariableDeclarationList &getGlobalVariables() { |
| - return VariableDeclarations; |
| + /// Returns the list of parsed global variable declarations. Releases |
| + /// ownership of the current list of global variables. |
| + std::unique_ptr<Ice::VariableDeclarationList> &&getGlobalVariables() { |
|
Jim Stichnoth
2015/02/10 17:47:11
Does this actually have to have "&&"? I thought i
Karl
2015/02/10 19:30:23
I thought that would be more efficient, but I'll r
|
| + // Before returning, check that ValidIDConstants has already been |
| + // build. |
|
Jim Stichnoth
2015/02/10 17:47:11
built
Karl
2015/02/10 19:30:23
Done.
|
| + assert(!VariableDeclarations || |
|
jvoung (off chromium)
2015/02/10 18:24:58
Why is it okay for "!VariableDeclarations"?
I ass
Jim Stichnoth
2015/02/10 18:29:01
Hmm, I was under the impression that this could po
Karl
2015/02/10 19:30:23
The code assumes it is only built once. I wanted t
|
| + VariableDeclarations->size() <= ValueIDConstants.size()); |
| + return std::move(VariableDeclarations); |
| } |
| private: |
| @@ -402,7 +374,7 @@ private: |
| // actually-defined function. |
| size_t NextDefiningFunctionID; |
| // The set of global variables. |
| - Ice::VariableDeclarationList VariableDeclarations; |
| + std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations; |
| // Relocatable constants associated with global declarations. |
| std::vector<Ice::Constant *> ValueIDConstants; |
| // Error recovery value to use when getFuncSigTypeByID fails. |
| @@ -432,6 +404,84 @@ private: |
| return nullptr; |
| } |
| + // Gives Decl a name if it doesn't already have one. Prefix and |
| + // NameIndex is used to generate the name. NameIndex is |
|
Jim Stichnoth
2015/02/10 17:47:11
are used
Karl
2015/02/10 19:30:23
Done.
|
| + // automatically incremented if a new new is created. |
|
Jim Stichnoth
2015/02/10 17:47:11
"new new" ==> ???
Karl
2015/02/10 19:30:23
Fixed.
|
| + // DeclType is literal text describing the type of name being |
| + // created. |
|
Jim Stichnoth
2015/02/10 17:47:11
Mention that it's used just for error reporting?
Karl
2015/02/10 19:30:23
This is not true. As stated in the comment, it cre
|
| + void installDeclarationName(Ice::GlobalDeclaration *Decl, |
| + const Ice::IceString &Prefix, |
| + const char *DeclType, uint32_t &NameIndex) { |
| + if (!Decl->hasName()) { |
|
Jim Stichnoth
2015/02/10 17:47:11
Rewrite as
if (Decl->hasName()) {
Translator...;
Karl
2015/02/10 19:30:22
Done.
|
| + Decl->setName(Translator.createUnnamedName(Prefix, NameIndex)); |
| + ++NameIndex; |
| + } else { |
| + Translator.checkIfUnnamedNameSafe(Decl->getName(), DeclType, Prefix); |
| + } |
| + } |
| + |
| + // Installs names for global variables without names. |
| + void installGlobalVarNames() { |
| + assert(VariableDeclarations); |
| + const Ice::IceString &GlobalPrefix = |
| + getTranslator().getFlags().getDefaultGlobalPrefix(); |
| + if (!GlobalPrefix.empty()) { |
| + uint32_t NameIndex = 0; |
| + for (Ice::VariableDeclaration *Var : *VariableDeclarations) { |
| + installDeclarationName(Var, GlobalPrefix, "global", NameIndex); |
| + } |
| + } |
| + } |
| + |
| + // Installs names for functions without names. |
| + void installFunctionNames() { |
| + const Ice::IceString &FunctionPrefix = |
| + getTranslator().getFlags().getDefaultFunctionPrefix(); |
| + if (!FunctionPrefix.empty()) { |
| + uint32_t NameIndex = 0; |
| + for (Ice::FunctionDeclaration *Func : FunctionDeclarationList) { |
| + installDeclarationName(Func, FunctionPrefix, "function", NameIndex); |
| + } |
| + } |
| + } |
| + |
| + // Builds a constant symbol named Name, suppressing name mangling if |
| + // SuppressMangling. IsExternal is true iff the symbol is external. |
| + Ice::Constant *getConstantSym(const Ice::IceString &Name, |
| + bool SuppressMangling, bool IsExternal) { |
| + if (IsExternal) { |
| + return getTranslator().getContext()->getConstantExternSym(Name); |
| + } else { |
| + const Ice::RelocOffsetT Offset = 0; |
| + return getTranslator().getContext()->getConstantSym(Offset, Name, |
| + SuppressMangling); |
| + } |
| + } |
| + |
| + // Converts function declarations into constant value IDs. |
| + void createValueIDsForFunctions() { |
| + for (Ice::FunctionDeclaration *Func : FunctionDeclarationList) { |
|
Jim Stichnoth
2015/02/10 17:47:11
Declare Func as const* if possible.
Karl
2015/02/10 19:30:23
Done.
|
| + Ice::Constant *C = nullptr; |
| + if (!isIRGenerationDisabled()) { |
| + C = getConstantSym(Func->getName(), Func->getSuppressMangling(), |
| + Func->isProto()); |
| + } |
| + ValueIDConstants.push_back(C); |
| + } |
| + } |
| + |
| + // Converts global variable declarations into constant value IDs. |
| + void createValueIDsForGlobalVars() { |
| + for (Ice::VariableDeclaration *Decl : *VariableDeclarations) { |
|
Jim Stichnoth
2015/02/10 17:47:11
Also declare Decl as const* if possible.
Karl
2015/02/10 19:30:23
Done.
|
| + Ice::Constant *C = nullptr; |
| + if (!isIRGenerationDisabled()) { |
| + C = getConstantSym(Decl->getName(), Decl->getSuppressMangling(), |
| + !Decl->hasInitializer()); |
| + } |
| + ValueIDConstants.push_back(C); |
| + } |
| + } |
| + |
| // Reports that type ID is undefined, or not of the WantedType. |
| void reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty, |
| ExtendedType::TypeKind WantedType); |
| @@ -494,11 +544,11 @@ TopLevelParser::reportGetGlobalVariableByIDError(unsigned Index) { |
| raw_string_ostream StrBuf(Buffer); |
| StrBuf << "Global index " << Index |
| << " not allowed. Out of range. Must be less than " |
| - << VariableDeclarations.size(); |
| + << VariableDeclarations->size(); |
| BlockError(StrBuf.str()); |
| // TODO(kschimpf) Remove error recovery once implementation complete. |
| - if (!VariableDeclarations.empty()) |
| - return VariableDeclarations[0]; |
| + if (!VariableDeclarations->empty()) |
| + return VariableDeclarations->at(0); |
| report_fatal_error("Unable to continue"); |
| } |
| @@ -1160,7 +1210,7 @@ public: |
| // Returns the value referenced by the given value Index. |
| Ice::Operand *getOperand(uint32_t Index) { |
| if (Index < CachedNumGlobalValueIDs) { |
| - return Context->getOrCreateGlobalConstantByID(Index); |
| + return Context->getGlobalConstantByID(Index); |
| } |
| uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; |
| if (LocalIndex >= LocalOperands.size()) { |
| @@ -2808,41 +2858,15 @@ private: |
| // the first call will do the installation. |
| void InstallGlobalNamesAndGlobalVarInitializers() { |
| if (!GlobalDeclarationNamesAndInitializersInstalled) { |
| - Ice::Translator &Trans = getTranslator(); |
| - const Ice::IceString &GlobalPrefix = getFlags().getDefaultGlobalPrefix(); |
| - if (!GlobalPrefix.empty()) { |
| - uint32_t NameIndex = 0; |
| - for (Ice::VariableDeclaration *Var : Context->getGlobalVariables()) { |
| - installDeclarationName(Trans, Var, GlobalPrefix, "global", NameIndex); |
| - } |
| - } |
| - const Ice::IceString &FunctionPrefix = |
| - getFlags().getDefaultFunctionPrefix(); |
| - if (!FunctionPrefix.empty()) { |
| - uint32_t NameIndex = 0; |
| - for (Ice::FunctionDeclaration *Func : |
| - Context->getFunctionDeclarationList()) { |
| - installDeclarationName(Trans, Func, FunctionPrefix, "function", |
| - NameIndex); |
| - } |
| - } |
| - getTranslator().lowerGlobals(Context->getGlobalVariables()); |
| + Context->installGlobalNames(); |
| + Context->createValueIDs(); |
| + std::unique_ptr<Ice::VariableDeclarationList> DeclsPtr = |
| + Context->getGlobalVariables(); |
| + const Ice::VariableDeclarationList &Decls = *DeclsPtr; |
| + getTranslator().lowerGlobals(Decls); |
| 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); |
| - } |
| - } |
| - |
| bool ParseBlock(unsigned BlockID) override; |
| void ExitBlock() override { InstallGlobalNamesAndGlobalVarInitializers(); } |