forked from OSchip/llvm-project
parent
6337d7b7c7
commit
44c1707207
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue