Add intrinsics for sin, cos, and pow. These use llvm_anyfloat_ty, and so
[oota-llvm.git] / lib / CodeGen / DwarfWriter.cpp
index 2b4b4ce135f3ffe7e769e4826621c0f07bd7a8a6..e6ec43eed3df86ffb83a3014dc04bc9688135862 100644 (file)
@@ -28,6 +28,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/Mangler.h"
+#include "llvm/System/Path.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/MRegisterInfo.h"
 #include "llvm/Target/TargetData.h"
@@ -798,9 +799,14 @@ protected:
   /// SubprogramCount - The running count of functions being compiled.
   ///
   unsigned SubprogramCount;
+  
+  /// Flavor - A unique string indicating what dwarf producer this is, used to
+  /// unique labels.
+  const char * const Flavor;
 
   unsigned SetCounter;
-  Dwarf(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T)
+  Dwarf(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T,
+        const char *flavor)
   : O(OS)
   , Asm(A)
   , TAI(T)
@@ -810,6 +816,7 @@ protected:
   , MF(NULL)
   , MMI(NULL)
   , SubprogramCount(0)
+  , Flavor(flavor)
   , SetCounter(1)
   {
   }
@@ -822,12 +829,13 @@ public:
   AsmPrinter *getAsm() const { return Asm; }
   MachineModuleInfo *getMMI() const { return MMI; }
   const TargetAsmInfo *getTargetAsmInfo() const { return TAI; }
+  const TargetData *getTargetData() const { return TD; }
 
   void PrintRelDirective(bool Force32Bit = false, bool isInSection = false)
                                                                          const {
     if (isInSection && TAI->getDwarfSectionOffsetDirective())
       O << TAI->getDwarfSectionOffsetDirective();
-    else if (Force32Bit || TAI->getAddressSize() == sizeof(int32_t))
+    else if (Force32Bit || TD->getPointerSize() == sizeof(int32_t))
       O << TAI->getData32bitsDirective();
     else
       O << TAI->getData64bitsDirective();
@@ -839,11 +847,17 @@ public:
     PrintLabelName(Label.Tag, Label.Number);
   }
   void PrintLabelName(const char *Tag, unsigned Number) const {
-    
     O << TAI->getPrivateGlobalPrefix() << Tag;
     if (Number) O << Number;
   }
   
+  void PrintLabelName(const char *Tag, unsigned Number,
+                      const char *Suffix) const {
+    O << TAI->getPrivateGlobalPrefix() << Tag;
+    if (Number) O << Number;
+    O << Suffix;
+  }
+  
   /// EmitLabel - Emit location label for internal use by Dwarf.
   ///
   void EmitLabel(DWLabel Label) const {
@@ -856,18 +870,20 @@ public:
   
   /// EmitReference - Emit a reference to a label.
   ///
-  void EmitReference(DWLabel Label, bool IsPCRelative = false) const {
-    EmitReference(Label.Tag, Label.Number, IsPCRelative);
+  void EmitReference(DWLabel Label, bool IsPCRelative = false,
+                     bool Force32Bit = false) const {
+    EmitReference(Label.Tag, Label.Number, IsPCRelative, Force32Bit);
   }
   void EmitReference(const char *Tag, unsigned Number,
-                     bool IsPCRelative = false) const {
-    PrintRelDirective();
+                     bool IsPCRelative = false, bool Force32Bit = false) const {
+    PrintRelDirective(Force32Bit);
     PrintLabelName(Tag, Number);
     
     if (IsPCRelative) O << "-" << TAI->getPCSymbol();
   }
-  void EmitReference(const std::string &Name, bool IsPCRelative = false) const {
-    PrintRelDirective();
+  void EmitReference(const std::string &Name, bool IsPCRelative = false,
+                     bool Force32Bit = false) const {
+    PrintRelDirective(Force32Bit);
     
     O << Name;
     
@@ -888,7 +904,7 @@ public:
                       bool IsSmall = false) {
     if (TAI->needsSet()) {
       O << "\t.set\t";
-      PrintLabelName("set", SetCounter);
+      PrintLabelName("set", SetCounter, Flavor);
       O << ",";
       PrintLabelName(TagHi, NumberHi);
       O << "-";
@@ -896,9 +912,7 @@ public:
       O << "\n";
 
       PrintRelDirective(IsSmall);
-        
-      PrintLabelName("set", SetCounter);
-      
+      PrintLabelName("set", SetCounter, Flavor);
       ++SetCounter;
     } else {
       PrintRelDirective(IsSmall);
@@ -915,7 +929,7 @@ public:
     bool printAbsolute = false;
     if (TAI->needsSet()) {
       O << "\t.set\t";
-      PrintLabelName("set", SetCounter);
+      PrintLabelName("set", SetCounter, Flavor);
       O << ",";
       PrintLabelName(Label, LabelNumber);
 
@@ -932,7 +946,7 @@ public:
 
       PrintRelDirective(IsSmall);
         
-      PrintLabelName("set", SetCounter);
+      PrintLabelName("set", SetCounter, Flavor);
       ++SetCounter;
     } else {
       PrintRelDirective(IsSmall, true);
@@ -958,7 +972,7 @@ public:
     int stackGrowth =
         Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
           TargetFrameInfo::StackGrowsUp ?
-            TAI->getAddressSize() : -TAI->getAddressSize();
+            TD->getPointerSize() : -TD->getPointerSize();
     bool IsLocal = BaseLabel && strcmp(BaseLabel, "label") == 0;
 
     for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
@@ -1301,7 +1315,9 @@ public:
       ValuesSet.InsertNode(Value, Where);
       Values.push_back(Value);
     } else {
+      // Already exists, reuse the previous one.
       delete Block;
+      Block = cast<DIEBlock>(Value);
     }
   
     Die->AddValue(Attribute, Block->BestForm(), Value);
@@ -1379,7 +1395,7 @@ private:
   ///
   DIE *ConstructPointerType(CompileUnit *Unit, const std::string &Name) {
     DIE Buffer(DW_TAG_pointer_type);
-    AddUInt(&Buffer, DW_AT_byte_size, 0, TAI->getAddressSize());
+    AddUInt(&Buffer, DW_AT_byte_size, 0, TD->getPointerSize());
     if (!Name.empty()) AddString(&Buffer, DW_AT_name, DW_FORM_string, Name);
     return Unit->AddDie(Buffer);
   }
@@ -2120,7 +2136,7 @@ private:
     Asm->EmitInt16(DWARF_VERSION); Asm->EOL("DWARF version number");
     EmitSectionOffset("abbrev_begin", "section_abbrev", 0, 0, true, false);
     Asm->EOL("Offset Into Abbrev. Section");
-    Asm->EmitInt8(TAI->getAddressSize()); Asm->EOL("Address Size (in bytes)");
+    Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)");
   
     EmitDIE(Die);
     // FIXME - extra padding for gdb bug.
@@ -2170,6 +2186,11 @@ private:
   /// EmitDebugLines - Emit source line information.
   ///
   void EmitDebugLines() {
+    // If there are no lines to emit (such as when we're using .loc directives
+    // to emit .debug_line information) don't emit a .debug_line header.
+    if (SectionSourceLines.empty())
+      return;
+
     // Minimum line delta, thus ranging from -10..(255-10).
     const int MinLineDelta = -(DW_LNS_fixed_advance_pc + 1);
     // Maximum line delta, thus ranging from -10..(255-10).
@@ -2266,7 +2287,7 @@ private:
 
         // Define the line address.
         Asm->EmitInt8(0); Asm->EOL("Extended Op");
-        Asm->EmitInt8(TAI->getAddressSize() + 1); Asm->EOL("Op size");
+        Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size");
         Asm->EmitInt8(DW_LNE_set_address); Asm->EOL("DW_LNE_set_address");
         EmitReference("label",  LabelID); Asm->EOL("Location label");
         
@@ -2304,7 +2325,7 @@ private:
 
       // Define last address of section.
       Asm->EmitInt8(0); Asm->EOL("Extended Op");
-      Asm->EmitInt8(TAI->getAddressSize() + 1); Asm->EOL("Op size");
+      Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size");
       Asm->EmitInt8(DW_LNE_set_address); Asm->EOL("DW_LNE_set_address");
       EmitReference("section_end", j + 1); Asm->EOL("Section end label");
 
@@ -2328,7 +2349,7 @@ private:
     int stackGrowth =
         Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
           TargetFrameInfo::StackGrowsUp ?
-        TAI->getAddressSize() : -TAI->getAddressSize();
+        TD->getPointerSize() : -TD->getPointerSize();
 
     // Start the dwarf frame section.
     Asm->SwitchToDataSection(TAI->getDwarfFrameSection());
@@ -2486,7 +2507,7 @@ private:
     EmitReference("info_begin", Unit->getID());
     Asm->EOL("Offset of Compilation Unit Info");
 
-    Asm->EmitInt8(TAI->getAddressSize()); Asm->EOL("Size of Address");
+    Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Size of Address");
 
     Asm->EmitInt8(0); Asm->EOL("Size of Segment Descriptor");
 
@@ -2499,9 +2520,9 @@ private:
 
     Asm->EmitInt32(0); Asm->EOL("EOM (1)");
     Asm->EmitInt32(0); Asm->EOL("EOM (2)");
+  #endif
     
     Asm->EOL();
-  #endif
   }
 
   /// EmitDebugRanges - Emit visible names into a debug ranges section.
@@ -2563,7 +2584,7 @@ public:
   // Main entry points.
   //
   DwarfDebug(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T)
-  : Dwarf(OS, A, T)
+  : Dwarf(OS, A, T, "dbg")
   , CompileUnits()
   , AbbreviationsSet(InitAbbreviationsSetSize)
   , Abbreviations()
@@ -2592,9 +2613,6 @@ public:
       MMI = mmi;
       shouldEmit = true;
       
-      // Emit initial sections
-      EmitInitial();
-    
       // Create all the compile unit DIEs.
       ConstructCompileUnitDIEs();
       
@@ -2606,6 +2624,23 @@ public:
       
       // Prime section data.
       SectionMap.insert(TAI->getTextSection());
+
+      // Print out .file directives to specify files for .loc directives. These
+      // are printed out early so that they precede any .loc directives.
+      if (TAI->hasDotLocAndDotFile()) {
+        const UniqueVector<SourceFileInfo> &SourceFiles = MMI->getSourceFiles();
+        const UniqueVector<std::string> &Directories = MMI->getDirectories();
+        for (unsigned i = 1, e = SourceFiles.size(); i <= e; ++i) {
+          sys::Path FullPath(Directories[SourceFiles[i].getDirectoryID()]);
+          bool AppendOk = FullPath.appendComponent(SourceFiles[i].getName());
+          assert(AppendOk && "Could not append filename to directory!");
+          Asm->EmitFile(i, FullPath.toString());
+          Asm->EOL();
+        }
+      }
+
+      // Emit initial sections
+      EmitInitial();
     }
   }
 
@@ -2750,7 +2785,7 @@ private:
     int stackGrowth =
         Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
           TargetFrameInfo::StackGrowsUp ?
-        TAI->getAddressSize() : -TAI->getAddressSize();
+        TD->getPointerSize() : -TD->getPointerSize();
 
     // Begin eh frame section.
     Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection());
@@ -2789,7 +2824,12 @@ private:
     if (Personality) {
       Asm->EmitULEB128Bytes(7);
       Asm->EOL("Augmentation Size");
-      Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect);
+
+      if (TAI->getNeedsIndirectEncoding())
+        Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect);
+      else
+        Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4);
+
       Asm->EOL("Personality (pcrel sdata4 indirect)");
       
       PrintRelDirective();
@@ -2828,13 +2868,13 @@ private:
 
     // Externally visible entry into the functions eh frame info.
     if (const char *GlobalDirective = TAI->getGlobalDirective())
-      O << GlobalDirective << EHFrameInfo.FnName << ".eh\n";
+      O << GlobalDirective << EHFrameInfo.FnName << "\n";
     
     // If there are no calls then you can't unwind.
     if (!EHFrameInfo.hasCalls) { 
-      O << EHFrameInfo.FnName << ".eh = 0\n";
+      O << EHFrameInfo.FnName << " = 0\n";
     } else {
-      O << EHFrameInfo.FnName << ".eh:\n";
+      O << EHFrameInfo.FnName << ":\n";
       
       // EH frame header.
       EmitDifference("eh_frame_end", EHFrameInfo.Number,
@@ -2862,7 +2902,7 @@ private:
         
         if (EHFrameInfo.hasLandingPads) {
           EmitReference("exception", EHFrameInfo.Number, true);
-        } else if(TAI->getAddressSize() == 8) {
+        } else if (TD->getPointerSize() == 8) {
           Asm->EmitInt64((int)0);
         } else {
           Asm->EmitInt32((int)0);
@@ -2882,7 +2922,7 @@ private:
     }
     
     if (const char *UsedDirective = TAI->getUsedDirective())
-      O << UsedDirective << EHFrameInfo.FnName << ".eh\n\n";
+      O << UsedDirective << EHFrameInfo.FnName << "\n\n";
   }
 
   /// EmitExceptionTable - Emit landing pads and actions.
@@ -2937,6 +2977,7 @@ private:
     static inline unsigned getEmptyKey() { return -1U; }
     static inline unsigned getTombstoneKey() { return -2U; }
     static unsigned getHashValue(const unsigned &Key) { return Key; }
+    static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; }
     static bool isPod() { return true; }
   };
 
@@ -3146,7 +3187,7 @@ private:
     for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
       SizeSites += Asm->SizeULEB128(CallSites[i].Action);
 
-    unsigned SizeTypes = TypeInfos.size() * TAI->getAddressSize();
+    unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
 
     unsigned TypeOffset = sizeof(int8_t) + // Call site format
                           Asm->SizeULEB128(SizeSites) + // Call-site table length
@@ -3207,7 +3248,7 @@ private:
       Asm->EOL("Region length");
 
       if (!S.PadLabel) {
-        if (TAI->getAddressSize() == sizeof(int32_t))
+        if (TD->getPointerSize() == sizeof(int32_t))
           Asm->EmitInt32(0);
         else
           Asm->EmitInt64(0);
@@ -3260,7 +3301,7 @@ public:
   // Main entry points.
   //
   DwarfException(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T)
-  : Dwarf(OS, A, T)
+  : Dwarf(OS, A, T, "eh")
   , shouldEmit(false)
   {}
   
@@ -3315,12 +3356,13 @@ public:
     EmitExceptionTable();
 
     // Save EH frame information
-    EHFrames.push_back(FunctionEHFrameInfo(getAsm()->CurrentFnName,
-                                           SubprogramCount,
-                                           MMI->getPersonalityIndex(),
-                                           MF->getFrameInfo()->hasCalls(),
-                                           !MMI->getLandingPads().empty(),
-                                           MMI->getFrameMoves()));
+    EHFrames.
+      push_back(FunctionEHFrameInfo(getAsm()->getCurrentFunctionEHName(MF),
+                                    SubprogramCount,
+                                    MMI->getPersonalityIndex(),
+                                    MF->getFrameInfo()->hasCalls(),
+                                    !MMI->getLandingPads().empty(),
+                                    MMI->getFrameMoves()));
   }
 };
 
@@ -3440,13 +3482,15 @@ void DIEString::EmitValue(DwarfDebug &DD, unsigned Form) {
 /// EmitValue - Emit label value.
 ///
 void DIEDwarfLabel::EmitValue(DwarfDebug &DD, unsigned Form) {
-  DD.EmitReference(Label);
+  bool IsSmall = Form == DW_FORM_data4;
+  DD.EmitReference(Label, false, IsSmall);
 }
 
 /// SizeOf - Determine size of label value in bytes.
 ///
 unsigned DIEDwarfLabel::SizeOf(const DwarfDebug &DD, unsigned Form) const {
-  return DD.getTargetAsmInfo()->getAddressSize();
+  if (Form == DW_FORM_data4) return 4;
+  return DD.getTargetData()->getPointerSize();
 }
 
 //===----------------------------------------------------------------------===//
@@ -3454,13 +3498,15 @@ unsigned DIEDwarfLabel::SizeOf(const DwarfDebug &DD, unsigned Form) const {
 /// EmitValue - Emit label value.
 ///
 void DIEObjectLabel::EmitValue(DwarfDebug &DD, unsigned Form) {
-  DD.EmitReference(Label);
+  bool IsSmall = Form == DW_FORM_data4;
+  DD.EmitReference(Label, false, IsSmall);
 }
 
 /// SizeOf - Determine size of label value in bytes.
 ///
 unsigned DIEObjectLabel::SizeOf(const DwarfDebug &DD, unsigned Form) const {
-  return DD.getTargetAsmInfo()->getAddressSize();
+  if (Form == DW_FORM_data4) return 4;
+  return DD.getTargetData()->getPointerSize();
 }
     
 //===----------------------------------------------------------------------===//
@@ -3476,7 +3522,7 @@ void DIEDelta::EmitValue(DwarfDebug &DD, unsigned Form) {
 ///
 unsigned DIEDelta::SizeOf(const DwarfDebug &DD, unsigned Form) const {
   if (Form == DW_FORM_data4) return 4;
-  return DD.getTargetAsmInfo()->getAddressSize();
+  return DD.getTargetData()->getPointerSize();
 }
 
 //===----------------------------------------------------------------------===//