[llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp

Chris Lattner lattner at cs.uiuc.edu
Tue Sep 9 11:24:03 PDT 2003


Changes in directory llvm/lib/Target/X86:

Printer.cpp updated: 1.59 -> 1.60

---
Log message:

* 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!


---
Diffs of the changes:

Index: llvm/lib/Target/X86/Printer.cpp
diff -u llvm/lib/Target/X86/Printer.cpp:1.59 llvm/lib/Target/X86/Printer.cpp:1.60
--- llvm/lib/Target/X86/Printer.cpp:1.59	Wed Aug 13 13:15:15 2003
+++ llvm/lib/Target/X86/Printer.cpp	Tue Sep  9 11:23:36 2003
@@ -71,7 +71,7 @@
     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 @@
 
 // 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
+  } 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";      
+    }
+    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 @@
   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 @@
   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\", at 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 << ", at 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 @@
         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
 }





More information about the llvm-commits mailing list