aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-09-09 16:23:36 +0000
committerChris Lattner <sabre@nondot.org>2003-09-09 16:23:36 +0000
commitad2007155991e3fdec348a4fdbfc9faab806721d (patch)
tree0865b757031b9e3e213fa622fb72514365364bbe /lib
parent38dc918cf55ab769b348abae65df590f75afec52 (diff)
downloadexternal_llvm-ad2007155991e3fdec348a4fdbfc9faab806721d.zip
external_llvm-ad2007155991e3fdec348a4fdbfc9faab806721d.tar.gz
external_llvm-ad2007155991e3fdec348a4fdbfc9faab806721d.tar.bz2
* Simplify printConstantValueOnly by moving the tail padding stuff directly
into the struct case. * Extend printConstantValueOnly to print .zero's if the initializer is zero * Delete dead isConstantFunctionPointerRef function * Emit the appropriate assembly for the various linkage types! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8417 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/X86/Printer.cpp155
-rw-r--r--lib/Target/X86/X86AsmPrinter.cpp155
2 files changed, 180 insertions, 130 deletions
diff --git a/lib/Target/X86/Printer.cpp b/lib/Target/X86/Printer.cpp
index 1a68844..0afd399 100644
--- a/lib/Target/X86/Printer.cpp
+++ b/lib/Target/X86/Printer.cpp
@@ -71,7 +71,7 @@ namespace {
std::string valToExprString(const Value* V);
bool doInitialization(Module &M);
bool doFinalization(Module &M);
- void printConstantValueOnly(const Constant* CV, int numPadBytesAfter = 0);
+ void printConstantValueOnly(const Constant* CV);
void printSingleConstantValue(const Constant* CV);
};
} // end of anonymous namespace
@@ -318,50 +318,45 @@ static std::string getAsCString(const ConstantArray *CVA) {
// Print a constant value or values (it may be an aggregate).
// Uses printSingleConstantValue() to print each individual value.
-void
-Printer::printConstantValueOnly(const Constant* CV,
- int numPadBytesAfter /* = 0 */)
-{
- const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
+void Printer::printConstantValueOnly(const Constant *CV) {
const TargetData &TD = TM.getTargetData();
- if (CVA && isStringCompatible(CVA))
- { // print the string alone and return
+ if (CV->isNullValue()) {
+ O << "\t.zero\t " << TD.getTypeSize(CV->getType()) << "\n";
+ } else if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
+ if (isStringCompatible(CVA)) {
+ // print the string alone and return
O << "\t.string\t" << getAsCString(CVA) << "\n";
- }
- else if (CVA)
- { // Not a string. Print the values in successive locations
+ } else { // Not a string. Print the values in successive locations
const std::vector<Use> &constValues = CVA->getValues();
for (unsigned i=0; i < constValues.size(); i++)
printConstantValueOnly(cast<Constant>(constValues[i].get()));
}
- else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
- { // Print the fields in successive locations. Pad to align if needed!
- const StructLayout *cvsLayout =
- TD.getStructLayout(CVS->getType());
- const std::vector<Use>& constValues = CVS->getValues();
- unsigned sizeSoFar = 0;
- for (unsigned i=0, N = constValues.size(); i < N; i++)
- {
- const Constant* field = cast<Constant>(constValues[i].get());
-
- // Check if padding is needed and insert one or more 0s.
- unsigned fieldSize = TD.getTypeSize(field->getType());
- int padSize = ((i == N-1? cvsLayout->StructSize
- : cvsLayout->MemberOffsets[i+1])
- - cvsLayout->MemberOffsets[i]) - fieldSize;
- sizeSoFar += (fieldSize + padSize);
-
- // Now print the actual field value
- printConstantValueOnly(field, padSize);
- }
- assert(sizeSoFar == cvsLayout->StructSize &&
- "Layout of constant struct may be incorrect!");
+ } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
+ // Print the fields in successive locations. Pad to align if needed!
+ const StructLayout *cvsLayout = TD.getStructLayout(CVS->getType());
+ const std::vector<Use>& constValues = CVS->getValues();
+ unsigned sizeSoFar = 0;
+ for (unsigned i=0, N = constValues.size(); i < N; i++) {
+ const Constant* field = cast<Constant>(constValues[i].get());
+
+ // Check if padding is needed and insert one or more 0s.
+ unsigned fieldSize = TD.getTypeSize(field->getType());
+ unsigned padSize = ((i == N-1? cvsLayout->StructSize
+ : cvsLayout->MemberOffsets[i+1])
+ - cvsLayout->MemberOffsets[i]) - fieldSize;
+ sizeSoFar += fieldSize + padSize;
+
+ // Now print the actual field value
+ printConstantValueOnly(field);
+
+ // Insert the field padding unless it's zero bytes...
+ O << "\t.zero\t " << padSize << "\n";
}
- else
+ assert(sizeSoFar == cvsLayout->StructSize &&
+ "Layout of constant struct may be incorrect!");
+ } else
printSingleConstantValue(CV);
-
- if (numPadBytesAfter) O << "\t.zero\t " << numPadBytesAfter << "\n";
}
/// printConstantPool - Print to the current output stream assembly
@@ -472,14 +467,13 @@ void Printer::printOp(const MachineOperand &MO,
case MachineOperand::MO_UnextendedImmed:
O << (int)MO.getImmedValue();
return;
- case MachineOperand::MO_PCRelativeDisp:
- {
- ValueMapTy::const_iterator i = NumberForBB.find(MO.getVRegValue());
- assert (i != NumberForBB.end()
- && "Could not find a BB I previously put in the NumberForBB map!");
- O << ".LBB" << i->second << " # PC rel: " << MO.getVRegValue()->getName();
- }
+ case MachineOperand::MO_PCRelativeDisp: {
+ ValueMapTy::const_iterator i = NumberForBB.find(MO.getVRegValue());
+ assert (i != NumberForBB.end()
+ && "Could not find a BB in the NumberForBB map!");
+ O << ".LBB" << i->second << " # PC rel: " << MO.getVRegValue()->getName();
return;
+ }
case MachineOperand::MO_GlobalAddress:
if (!elideOffsetKeyword)
O << "OFFSET ";
@@ -923,33 +917,69 @@ bool Printer::doInitialization(Module &M) {
return false; // success
}
-static const Function *isConstantFunctionPointerRef(const Constant *C) {
- if (const ConstantPointerRef *R = dyn_cast<ConstantPointerRef>(C))
- if (const Function *F = dyn_cast<Function>(R->getValue()))
- return F;
- return 0;
+// SwitchSection - Switch to the specified section of the executable if we are
+// not already in it!
+//
+static void SwitchSection(std::ostream &OS, std::string &CurSection,
+ const char *NewSection) {
+ if (CurSection != NewSection) {
+ CurSection = NewSection;
+ if (!CurSection.empty())
+ OS << "\t" << NewSection << "\n";
+ }
}
-bool Printer::doFinalization(Module &M)
-{
+bool Printer::doFinalization(Module &M) {
const TargetData &TD = TM.getTargetData();
+ std::string CurSection;
+
// Print out module-level global variables here.
- for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) {
- std::string name(Mang->getValueName(I));
- if (I->hasInitializer()) {
+ for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
+ if (I->hasInitializer()) { // External global require no code
+ O << "\n\n";
+ std::string name = Mang->getValueName(I);
Constant *C = I->getInitializer();
- if (C->isNullValue()) {
- O << "\n\n\t.comm " << name << "," << TD.getTypeSize(C->getType())
+ unsigned Size = TD.getTypeSize(C->getType());
+ unsigned Align = TD.getTypeAlignment(C->getType());
+
+ if (C->isNullValue() &&
+ (I->hasLinkOnceLinkage() || I->hasInternalLinkage())) {
+ SwitchSection(O, CurSection, ".data");
+ if (I->hasInternalLinkage())
+ O << "\t.local " << name << "\n";
+
+ O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
<< "," << (unsigned)TD.getTypeAlignment(C->getType());
O << "\t\t# ";
WriteAsOperand(O, I, true, true, &M);
O << "\n";
} else {
- O << "\n\n\t.data\n";
- O << "\t.globl " << name << "\n";
+ switch (I->getLinkage()) {
+ case GlobalValue::LinkOnceLinkage:
+ // Nonnull linkonce -> weak
+ O << "\t.weak " << name << "\n";
+ SwitchSection(O, CurSection, "");
+ O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
+ break;
+
+ case GlobalValue::AppendingLinkage:
+ // FIXME: appending linkage variables should go into a section of
+ // their name or something. For now, just emit them as external.
+ case GlobalValue::ExternalLinkage:
+ // If external or appending, declare as a global symbol
+ O << "\t.globl " << name << "\n";
+ // FALL THROUGH
+ case GlobalValue::InternalLinkage:
+ if (C->isNullValue())
+ SwitchSection(O, CurSection, ".bss");
+ else
+ SwitchSection(O, CurSection, ".data");
+ break;
+ }
+
+ O << "\t.align " << Align << "\n";
O << "\t.type " << name << ",@object\n";
- O << "\t.size " << name << "," << TD.getTypeSize(C->getType()) << "\n";
- O << "\t.align " << (unsigned)TD.getTypeAlignment(C->getType()) << "\n";
+ O << "\t.size " << name << "," << Size << "\n";
O << name << ":\t\t\t\t# ";
WriteAsOperand(O, I, true, true, &M);
O << " = ";
@@ -957,13 +987,8 @@ bool Printer::doFinalization(Module &M)
O << "\n";
printConstantValueOnly(C);
}
- } else {
- O << "\t.globl " << name << "\n";
- O << "\t.comm " << name << ", "
- << (unsigned)TD.getTypeSize(I->getType()) << ", "
- << (unsigned)TD.getTypeAlignment(I->getType()) << "\n";
}
- }
+
delete Mang;
return false; // success
}
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
index 1a68844..0afd399 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -71,7 +71,7 @@ namespace {
std::string valToExprString(const Value* V);
bool doInitialization(Module &M);
bool doFinalization(Module &M);
- void printConstantValueOnly(const Constant* CV, int numPadBytesAfter = 0);
+ void printConstantValueOnly(const Constant* CV);
void printSingleConstantValue(const Constant* CV);
};
} // end of anonymous namespace
@@ -318,50 +318,45 @@ static std::string getAsCString(const ConstantArray *CVA) {
// Print a constant value or values (it may be an aggregate).
// Uses printSingleConstantValue() to print each individual value.
-void
-Printer::printConstantValueOnly(const Constant* CV,
- int numPadBytesAfter /* = 0 */)
-{
- const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
+void Printer::printConstantValueOnly(const Constant *CV) {
const TargetData &TD = TM.getTargetData();
- if (CVA && isStringCompatible(CVA))
- { // print the string alone and return
+ if (CV->isNullValue()) {
+ O << "\t.zero\t " << TD.getTypeSize(CV->getType()) << "\n";
+ } else if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
+ if (isStringCompatible(CVA)) {
+ // print the string alone and return
O << "\t.string\t" << getAsCString(CVA) << "\n";
- }
- else if (CVA)
- { // Not a string. Print the values in successive locations
+ } else { // Not a string. Print the values in successive locations
const std::vector<Use> &constValues = CVA->getValues();
for (unsigned i=0; i < constValues.size(); i++)
printConstantValueOnly(cast<Constant>(constValues[i].get()));
}
- else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
- { // Print the fields in successive locations. Pad to align if needed!
- const StructLayout *cvsLayout =
- TD.getStructLayout(CVS->getType());
- const std::vector<Use>& constValues = CVS->getValues();
- unsigned sizeSoFar = 0;
- for (unsigned i=0, N = constValues.size(); i < N; i++)
- {
- const Constant* field = cast<Constant>(constValues[i].get());
-
- // Check if padding is needed and insert one or more 0s.
- unsigned fieldSize = TD.getTypeSize(field->getType());
- int padSize = ((i == N-1? cvsLayout->StructSize
- : cvsLayout->MemberOffsets[i+1])
- - cvsLayout->MemberOffsets[i]) - fieldSize;
- sizeSoFar += (fieldSize + padSize);
-
- // Now print the actual field value
- printConstantValueOnly(field, padSize);
- }
- assert(sizeSoFar == cvsLayout->StructSize &&
- "Layout of constant struct may be incorrect!");
+ } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
+ // Print the fields in successive locations. Pad to align if needed!
+ const StructLayout *cvsLayout = TD.getStructLayout(CVS->getType());
+ const std::vector<Use>& constValues = CVS->getValues();
+ unsigned sizeSoFar = 0;
+ for (unsigned i=0, N = constValues.size(); i < N; i++) {
+ const Constant* field = cast<Constant>(constValues[i].get());
+
+ // Check if padding is needed and insert one or more 0s.
+ unsigned fieldSize = TD.getTypeSize(field->getType());
+ unsigned padSize = ((i == N-1? cvsLayout->StructSize
+ : cvsLayout->MemberOffsets[i+1])
+ - cvsLayout->MemberOffsets[i]) - fieldSize;
+ sizeSoFar += fieldSize + padSize;
+
+ // Now print the actual field value
+ printConstantValueOnly(field);
+
+ // Insert the field padding unless it's zero bytes...
+ O << "\t.zero\t " << padSize << "\n";
}
- else
+ assert(sizeSoFar == cvsLayout->StructSize &&
+ "Layout of constant struct may be incorrect!");
+ } else
printSingleConstantValue(CV);
-
- if (numPadBytesAfter) O << "\t.zero\t " << numPadBytesAfter << "\n";
}
/// printConstantPool - Print to the current output stream assembly
@@ -472,14 +467,13 @@ void Printer::printOp(const MachineOperand &MO,
case MachineOperand::MO_UnextendedImmed:
O << (int)MO.getImmedValue();
return;
- case MachineOperand::MO_PCRelativeDisp:
- {
- ValueMapTy::const_iterator i = NumberForBB.find(MO.getVRegValue());
- assert (i != NumberForBB.end()
- && "Could not find a BB I previously put in the NumberForBB map!");
- O << ".LBB" << i->second << " # PC rel: " << MO.getVRegValue()->getName();
- }
+ case MachineOperand::MO_PCRelativeDisp: {
+ ValueMapTy::const_iterator i = NumberForBB.find(MO.getVRegValue());
+ assert (i != NumberForBB.end()
+ && "Could not find a BB in the NumberForBB map!");
+ O << ".LBB" << i->second << " # PC rel: " << MO.getVRegValue()->getName();
return;
+ }
case MachineOperand::MO_GlobalAddress:
if (!elideOffsetKeyword)
O << "OFFSET ";
@@ -923,33 +917,69 @@ bool Printer::doInitialization(Module &M) {
return false; // success
}
-static const Function *isConstantFunctionPointerRef(const Constant *C) {
- if (const ConstantPointerRef *R = dyn_cast<ConstantPointerRef>(C))
- if (const Function *F = dyn_cast<Function>(R->getValue()))
- return F;
- return 0;
+// SwitchSection - Switch to the specified section of the executable if we are
+// not already in it!
+//
+static void SwitchSection(std::ostream &OS, std::string &CurSection,
+ const char *NewSection) {
+ if (CurSection != NewSection) {
+ CurSection = NewSection;
+ if (!CurSection.empty())
+ OS << "\t" << NewSection << "\n";
+ }
}
-bool Printer::doFinalization(Module &M)
-{
+bool Printer::doFinalization(Module &M) {
const TargetData &TD = TM.getTargetData();
+ std::string CurSection;
+
// Print out module-level global variables here.
- for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) {
- std::string name(Mang->getValueName(I));
- if (I->hasInitializer()) {
+ for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
+ if (I->hasInitializer()) { // External global require no code
+ O << "\n\n";
+ std::string name = Mang->getValueName(I);
Constant *C = I->getInitializer();
- if (C->isNullValue()) {
- O << "\n\n\t.comm " << name << "," << TD.getTypeSize(C->getType())
+ unsigned Size = TD.getTypeSize(C->getType());
+ unsigned Align = TD.getTypeAlignment(C->getType());
+
+ if (C->isNullValue() &&
+ (I->hasLinkOnceLinkage() || I->hasInternalLinkage())) {
+ SwitchSection(O, CurSection, ".data");
+ if (I->hasInternalLinkage())
+ O << "\t.local " << name << "\n";
+
+ O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
<< "," << (unsigned)TD.getTypeAlignment(C->getType());
O << "\t\t# ";
WriteAsOperand(O, I, true, true, &M);
O << "\n";
} else {
- O << "\n\n\t.data\n";
- O << "\t.globl " << name << "\n";
+ switch (I->getLinkage()) {
+ case GlobalValue::LinkOnceLinkage:
+ // Nonnull linkonce -> weak
+ O << "\t.weak " << name << "\n";
+ SwitchSection(O, CurSection, "");
+ O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
+ break;
+
+ case GlobalValue::AppendingLinkage:
+ // FIXME: appending linkage variables should go into a section of
+ // their name or something. For now, just emit them as external.
+ case GlobalValue::ExternalLinkage:
+ // If external or appending, declare as a global symbol
+ O << "\t.globl " << name << "\n";
+ // FALL THROUGH
+ case GlobalValue::InternalLinkage:
+ if (C->isNullValue())
+ SwitchSection(O, CurSection, ".bss");
+ else
+ SwitchSection(O, CurSection, ".data");
+ break;
+ }
+
+ O << "\t.align " << Align << "\n";
O << "\t.type " << name << ",@object\n";
- O << "\t.size " << name << "," << TD.getTypeSize(C->getType()) << "\n";
- O << "\t.align " << (unsigned)TD.getTypeAlignment(C->getType()) << "\n";
+ O << "\t.size " << name << "," << Size << "\n";
O << name << ":\t\t\t\t# ";
WriteAsOperand(O, I, true, true, &M);
O << " = ";
@@ -957,13 +987,8 @@ bool Printer::doFinalization(Module &M)
O << "\n";
printConstantValueOnly(C);
}
- } else {
- O << "\t.globl " << name << "\n";
- O << "\t.comm " << name << ", "
- << (unsigned)TD.getTypeSize(I->getType()) << ", "
- << (unsigned)TD.getTypeAlignment(I->getType()) << "\n";
}
- }
+
delete Mang;
return false; // success
}