add bitcode alias support

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36461 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-04-26 02:46:40 +00:00
parent d743f0e8f2
commit 07d98b4afb
4 changed files with 81 additions and 17 deletions

View File

@ -398,6 +398,47 @@ static uint64_t DecodeSignRotatedValue(uint64_t V) {
return 1ULL << 63; return 1ULL << 63;
} }
/// ResolveGlobalAndAliasInits - Resolve all of the initializers for global
/// values and aliases that we can.
bool BitcodeReader::ResolveGlobalAndAliasInits() {
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist;
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist;
GlobalInitWorklist.swap(GlobalInits);
AliasInitWorklist.swap(AliasInits);
while (!GlobalInitWorklist.empty()) {
unsigned ValID = GlobalInits.back().second;
if (ValID >= ValueList.size()) {
// Not ready to resolve this yet, it requires something later in the file.
GlobalInitWorklist.push_back(GlobalInits.back());
} else {
if (Constant *C = dyn_cast<Constant>(ValueList[ValID]))
GlobalInitWorklist.back().first->setInitializer(C);
else
return Error("Global variable initializer is not a constant!");
}
GlobalInitWorklist.pop_back();
}
while (!AliasInitWorklist.empty()) {
unsigned ValID = AliasInitWorklist.back().second;
if (ValID >= ValueList.size()) {
AliasInits.push_back(AliasInitWorklist.back());
} else {
if (Constant *C = dyn_cast<Constant>(ValueList[ValID]))
AliasInitWorklist.back().first->setAliasee(
// FIXME:
cast<GlobalValue>(C));
else
return Error("Alias initializer is not a constant!");
}
AliasInitWorklist.pop_back();
}
return false;
}
bool BitcodeReader::ParseConstants(BitstreamReader &Stream) { bool BitcodeReader::ParseConstants(BitstreamReader &Stream) {
if (Stream.EnterSubBlock()) if (Stream.EnterSubBlock())
return Error("Malformed block record"); return Error("Malformed block record");
@ -410,20 +451,6 @@ bool BitcodeReader::ParseConstants(BitstreamReader &Stream) {
while (1) { while (1) {
unsigned Code = Stream.ReadCode(); unsigned Code = Stream.ReadCode();
if (Code == bitc::END_BLOCK) { if (Code == bitc::END_BLOCK) {
// If there are global var inits to process, do so now.
if (!GlobalInits.empty()) {
while (!GlobalInits.empty()) {
unsigned ValID = GlobalInits.back().second;
if (ValID >= ValueList.size())
return Error("Invalid value ID for global var init!");
if (Constant *C = dyn_cast<Constant>(ValueList[ValID]))
GlobalInits.back().first->setInitializer(C);
else
return Error("Global variable initializer is not a constant!");
GlobalInits.pop_back();
}
}
if (NextCstNo != ValueList.size()) if (NextCstNo != ValueList.size())
return Error("Invalid constant reference!"); return Error("Invalid constant reference!");
@ -646,7 +673,8 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream,
while (!Stream.AtEndOfStream()) { while (!Stream.AtEndOfStream()) {
unsigned Code = Stream.ReadCode(); unsigned Code = Stream.ReadCode();
if (Code == bitc::END_BLOCK) { if (Code == bitc::END_BLOCK) {
if (!GlobalInits.empty()) ResolveGlobalAndAliasInits();
if (!GlobalInits.empty() || !AliasInits.empty())
return Error("Malformed global initializer set"); return Error("Malformed global initializer set");
if (Stream.ReadBlockEnd()) if (Stream.ReadBlockEnd())
return Error("Error at end of module block"); return Error("Error at end of module block");
@ -672,7 +700,7 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream,
return true; return true;
break; break;
case bitc::CONSTANTS_BLOCK_ID: case bitc::CONSTANTS_BLOCK_ID:
if (ParseConstants(Stream)) if (ParseConstants(Stream) || ResolveGlobalAndAliasInits())
return true; return true;
break; break;
} }
@ -795,9 +823,21 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream,
Func->setVisibility(GetDecodedVisibility(Record[6])); Func->setVisibility(GetDecodedVisibility(Record[6]));
ValueList.push_back(Func); ValueList.push_back(Func);
// TODO: remember initializer/global pair for later substitution.
break; break;
} }
// ALIAS: [alias type, aliasee val#, linkage]
case bitc::MODULE_CODE_ALIAS:
if (Record.size() < 3)
return Error("Invalid MODULE_ALIAS record");
const Type *Ty = getTypeByID(Record[0]);
if (!isa<PointerType>(Ty))
return Error("Function not a pointer type!");
GlobalAlias *NewGA = new GlobalAlias(Ty, GetDecodedLinkage(Record[2]),
"", 0, TheModule);
ValueList.push_back(NewGA);
AliasInits.push_back(std::make_pair(NewGA, Record[1]));
break;
} }
Record.clear(); Record.clear();
} }

View File

@ -57,6 +57,7 @@ class BitcodeReader : public ModuleProvider {
std::vector<PATypeHolder> TypeList; std::vector<PATypeHolder> TypeList;
BitcodeReaderValueList ValueList; BitcodeReaderValueList ValueList;
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits; std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
public: public:
BitcodeReader() : ErrorString(0) {} BitcodeReader() : ErrorString(0) {}
virtual ~BitcodeReader() {} virtual ~BitcodeReader() {}
@ -93,6 +94,7 @@ private:
bool ParseTypeSymbolTable(BitstreamReader &Stream); bool ParseTypeSymbolTable(BitstreamReader &Stream);
bool ParseValueSymbolTable(BitstreamReader &Stream); bool ParseValueSymbolTable(BitstreamReader &Stream);
bool ParseConstants(BitstreamReader &Stream); bool ParseConstants(BitstreamReader &Stream);
bool ResolveGlobalAndAliasInits();
}; };
} // End llvm namespace } // End llvm namespace

View File

@ -309,6 +309,18 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse); Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
Vals.clear(); Vals.clear();
} }
// Emit the alias information.
for (Module::const_alias_iterator AI = M->alias_begin(), E = M->alias_end();
AI != E; ++AI) {
Vals.push_back(VE.getTypeID(AI->getType()));
Vals.push_back(VE.getValueID(AI->getAliasee()));
Vals.push_back(getEncodedLinkage(AI));
unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
Vals.clear();
}
} }

View File

@ -28,12 +28,22 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
EnumerateValue(I); EnumerateValue(I);
// Enumerate the aliases.
for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
I != E; ++I)
EnumerateValue(I);
// Enumerate the global variable initializers. // Enumerate the global variable initializers.
for (Module::const_global_iterator I = M->global_begin(), for (Module::const_global_iterator I = M->global_begin(),
E = M->global_end(); I != E; ++I) E = M->global_end(); I != E; ++I)
if (I->hasInitializer()) if (I->hasInitializer())
EnumerateValue(I->getInitializer()); EnumerateValue(I->getInitializer());
// Enumerate the aliasees.
for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
I != E; ++I)
EnumerateValue(I->getAliasee());
// FIXME: Implement the 'string constant' optimization. // FIXME: Implement the 'string constant' optimization.
// Enumerate types used by the type symbol table. // Enumerate types used by the type symbol table.