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;
}
/// 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) {
if (Stream.EnterSubBlock())
return Error("Malformed block record");
@ -410,20 +451,6 @@ bool BitcodeReader::ParseConstants(BitstreamReader &Stream) {
while (1) {
unsigned Code = Stream.ReadCode();
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())
return Error("Invalid constant reference!");
@ -646,7 +673,8 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream,
while (!Stream.AtEndOfStream()) {
unsigned Code = Stream.ReadCode();
if (Code == bitc::END_BLOCK) {
if (!GlobalInits.empty())
ResolveGlobalAndAliasInits();
if (!GlobalInits.empty() || !AliasInits.empty())
return Error("Malformed global initializer set");
if (Stream.ReadBlockEnd())
return Error("Error at end of module block");
@ -672,7 +700,7 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream,
return true;
break;
case bitc::CONSTANTS_BLOCK_ID:
if (ParseConstants(Stream))
if (ParseConstants(Stream) || ResolveGlobalAndAliasInits())
return true;
break;
}
@ -795,9 +823,21 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream,
Func->setVisibility(GetDecodedVisibility(Record[6]));
ValueList.push_back(Func);
// TODO: remember initializer/global pair for later substitution.
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();
}

View File

@ -57,6 +57,7 @@ class BitcodeReader : public ModuleProvider {
std::vector<PATypeHolder> TypeList;
BitcodeReaderValueList ValueList;
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
public:
BitcodeReader() : ErrorString(0) {}
virtual ~BitcodeReader() {}
@ -93,6 +94,7 @@ private:
bool ParseTypeSymbolTable(BitstreamReader &Stream);
bool ParseValueSymbolTable(BitstreamReader &Stream);
bool ParseConstants(BitstreamReader &Stream);
bool ResolveGlobalAndAliasInits();
};
} // 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);
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)
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.
for (Module::const_global_iterator I = M->global_begin(),
E = M->global_end(); I != E; ++I)
if (I->hasInitializer())
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.
// Enumerate types used by the type symbol table.