Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Unified Diff: src/PNaClTranslator.cpp

Issue 883673005: Fix PNaCl bitcode reader to release global variables to emitter. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix issues in patch set 3. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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(); }
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698