mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-03 17:31:50 +00:00
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:
parent
d743f0e8f2
commit
07d98b4afb
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user