aboutsummaryrefslogtreecommitdiff
path: root/lib/Bytecode
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bytecode')
-rw-r--r--lib/Bytecode/Reader/Reader.cpp55
-rw-r--r--lib/Bytecode/Reader/ReaderInternals.h1
-rw-r--r--lib/Bytecode/Writer/Writer.cpp12
3 files changed, 48 insertions, 20 deletions
diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp
index fb561aa16c..c8bf5af72e 100644
--- a/lib/Bytecode/Reader/Reader.cpp
+++ b/lib/Bytecode/Reader/Reader.cpp
@@ -301,14 +301,24 @@ bool BytecodeParser::ParseFunction(const uchar *&Buf, const uchar *EndBuf) {
return true; // Unexpected function!
}
- unsigned isInternal;
- if (read_vbr(Buf, EndBuf, isInternal)) return true;
+ GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage;
+
+ if (!hasInternalMarkerOnly) {
+ unsigned LinkageType;
+ if (read_vbr(Buf, EndBuf, LinkageType)) return true;
+ if (LinkageType & 0x3) return true;
+ Linkage = (GlobalValue::LinkageTypes)LinkageType;
+ } else {
+ // We used to only support two linkage models: internal and external
+ unsigned isInternal;
+ if (read_vbr(Buf, EndBuf, isInternal)) return true;
+ if (isInternal) Linkage = GlobalValue::InternalLinkage;
+ }
Function *F = FunctionSignatureList.back().first;
unsigned FunctionSlot = FunctionSignatureList.back().second;
FunctionSignatureList.pop_back();
- F->setLinkage(isInternal ? GlobalValue::InternalLinkage :
- GlobalValue::ExternalLinkage);
+ F->setLinkage(Linkage);
const FunctionType::ParamTypes &Params =F->getFunctionType()->getParamTypes();
Function::aiterator AI = F->abegin();
@@ -390,9 +400,23 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End){
unsigned VarType;
if (read_vbr(Buf, End, VarType)) return true;
while (VarType != Type::VoidTyID) { // List is terminated by Void
- // VarType Fields: bit0 = isConstant, bit1 = hasInitializer,
- // bit2 = isInternal, bit3+ = slot#
- const Type *Ty = getType(VarType >> 3);
+ unsigned SlotNo;
+ GlobalValue::LinkageTypes Linkage;
+
+ if (!hasInternalMarkerOnly) {
+ // VarType Fields: bit0 = isConstant, bit1 = hasInitializer,
+ // bit2,3 = Linkage, bit4+ = slot#
+ SlotNo = VarType >> 4;
+ Linkage = (GlobalValue::LinkageTypes)((VarType >> 2) & 3);
+ } else {
+ // VarType Fields: bit0 = isConstant, bit1 = hasInitializer,
+ // bit2 = isInternal, bit3+ = slot#
+ SlotNo = VarType >> 3;
+ Linkage = (VarType & 4) ? GlobalValue::InternalLinkage :
+ GlobalValue::ExternalLinkage;
+ }
+
+ const Type *Ty = getType(SlotNo);
if (!Ty || !isa<PointerType>(Ty)) {
Error = "Global not pointer type! Ty = " + Ty->getDescription();
return true;
@@ -400,11 +424,6 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End){
const Type *ElTy = cast<PointerType>(Ty)->getElementType();
-
- GlobalValue::LinkageTypes Linkage =
- (VarType & 4) ? GlobalValue::InternalLinkage :
- GlobalValue::ExternalLinkage;
-
// Create the global variable...
GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, Linkage,
0, "", TheModule);
@@ -477,7 +496,11 @@ bool BytecodeParser::ParseVersionInfo(const uchar *&Buf, const uchar *EndBuf) {
isBigEndian = Version & 1;
hasLongPointers = Version & 2;
RevisionNum = Version >> 4;
+
+ // Default values for the current bytecode version
HasImplicitZeroInitializer = true;
+ hasInternalMarkerOnly = false;
+ FirstDerivedTyID = 14;
switch (RevisionNum) {
case 0: // Initial revision
@@ -486,13 +509,17 @@ bool BytecodeParser::ParseVersionInfo(const uchar *&Buf, const uchar *EndBuf) {
// encoding zero initializers for arrays compactly.
//
if (Version != 14) return true; // Unknown revision 0 flags?
- FirstDerivedTyID = 14;
HasImplicitZeroInitializer = false;
isBigEndian = hasLongPointers = true;
+ hasInternalMarkerOnly = true;
break;
case 1:
// Version #1 has two bit fields: isBigEndian and hasLongPointers
- FirstDerivedTyID = 14;
+ hasInternalMarkerOnly = true;
+ break;
+ case 2:
+ // Version #2 added information about all 4 linkage types instead of just
+ // having internal and external.
break;
default:
Error = "Unknown bytecode version number!";
diff --git a/lib/Bytecode/Reader/ReaderInternals.h b/lib/Bytecode/Reader/ReaderInternals.h
index 3e571f2ee8..dd2a08fcdb 100644
--- a/lib/Bytecode/Reader/ReaderInternals.h
+++ b/lib/Bytecode/Reader/ReaderInternals.h
@@ -85,6 +85,7 @@ private: // All of this data is transient across calls to ParseBytecode
unsigned char FirstDerivedTyID; // First variable index to use for type
bool HasImplicitZeroInitializer; // Is entry 0 of every slot implicity zeros?
bool isBigEndian, hasLongPointers;// Information about the target compiled for
+ bool hasInternalMarkerOnly; // Only types of linkage are intern/external
typedef std::vector<ValueList*> ValueTable;
ValueTable Values, LateResolveValues;
diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp
index 8f4f785c4d..03a6c4668e 100644
--- a/lib/Bytecode/Writer/Writer.cpp
+++ b/lib/Bytecode/Writer/Writer.cpp
@@ -46,8 +46,8 @@ BytecodeWriter::BytecodeWriter(std::deque<unsigned char> &o, const Module *M)
bool isBigEndian = true;
bool hasLongPointers = true;
- // Output the version identifier... we are currently on bytecode version #1
- unsigned Version = (1 << 4) | isBigEndian | (hasLongPointers << 1);
+ // Output the version identifier... we are currently on bytecode version #2
+ unsigned Version = (2 << 4) | isBigEndian | (hasLongPointers << 1);
output_vbr(Version, Out);
align32(Out);
@@ -154,9 +154,9 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
int Slot = Table.getValSlot(I->getType());
assert(Slot != -1 && "Module global vars is broken!");
- // Fields: bit0 = isConstant, bit1 = hasInitializer, bit2=InternalLinkage,
- // bit3+ = Slot # for type
- unsigned oSlot = ((unsigned)Slot << 3) | (I->hasInternalLinkage() << 2) |
+ // Fields: bit0 = isConstant, bit1 = hasInitializer, bit2,3=Linkage,
+ // bit4+ = Slot # for type
+ unsigned oSlot = ((unsigned)Slot << 4) | ((unsigned)I->getLinkage() << 2) |
(I->hasInitializer() << 1) | I->isConstant();
output_vbr(oSlot, Out);
@@ -183,7 +183,7 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
void BytecodeWriter::outputFunction(const Function *F) {
BytecodeBlock FunctionBlock(BytecodeFormat::Function, Out);
- output_vbr((unsigned)F->hasInternalLinkage(), Out);
+ output_vbr((unsigned)F->getLinkage(), Out);
// Only output the constant pool and other goodies if needed...
if (!F->isExternal()) {