There are times when the coalescer would not coalesce away a copy but the copy
[oota-llvm.git] / lib / CodeGen / MachineModuleInfo.cpp
index adf7d29c0498c6481089a4f151a57dabff6eb7ec..8360745ff167268a5c6619287b56f3ee2875e067 100644 (file)
@@ -30,6 +30,7 @@ using namespace llvm::dwarf;
 namespace {
   RegisterPass<MachineModuleInfo> X("machinemoduleinfo", "Module Information");
 }
+char MachineModuleInfo::ID = 0;
 
 //===----------------------------------------------------------------------===//
 
@@ -1322,7 +1323,7 @@ Constant *DISerializer::getString(const std::string &String) {
     // Otherwise create and return a new string global.
     GlobalVariable *StrGV = new GlobalVariable(ConstStr->getType(), true,
                                                GlobalVariable::InternalLinkage,
-                                               ConstStr, "str", M);
+                                               ConstStr, ".str", M);
     StrGV->setSection("llvm.metadata");
     // Convert to generic string pointer.
     Slot = ConstantExpr::getBitCast(StrGV, getStrPtrType());
@@ -1462,7 +1463,8 @@ DebugScope::~DebugScope() {
 //===----------------------------------------------------------------------===//
 
 MachineModuleInfo::MachineModuleInfo()
-: DR()
+: ImmutablePass((intptr_t)&ID)
+, DR()
 , VR()
 , CompileUnits()
 , Directories()
@@ -1473,7 +1475,13 @@ MachineModuleInfo::MachineModuleInfo()
 , RootScope(NULL)
 , FrameMoves()
 , LandingPads()
-{}
+, Personalities()
+, CallsEHReturn(0)
+, CallsUnwindInit(0)
+{
+  // Always emit "no personality" info
+  Personalities.push_back(NULL);
+}
 MachineModuleInfo::~MachineModuleInfo() {
 
 }
@@ -1515,6 +1523,10 @@ void MachineModuleInfo::EndFunction() {
   // Clean up exception info.
   LandingPads.clear();
   TypeInfos.clear();
+  FilterIds.clear();
+  FilterEnds.clear();
+  CallsEHReturn = 0;
+  CallsUnwindInit = 0;
 }
 
 /// getDescFor - Convert a Value to a debug information descriptor.
@@ -1653,9 +1665,9 @@ LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo
     (MachineBasicBlock *LandingPad) {
   unsigned N = LandingPads.size();
   for (unsigned i = 0; i < N; ++i) {
-    LandingPadInfo &UI = LandingPads[i];
-    if (UI.LandingPadBlock == LandingPad)
-      return UI;
+    LandingPadInfo &LP = LandingPads[i];
+    if (LP.LandingPadBlock == LandingPad)
+      return LP;
   }
   
   LandingPads.push_back(LandingPadInfo(LandingPad));
@@ -1666,17 +1678,17 @@ LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo
 /// associate it with a try landing pad block.
 void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad,
                                   unsigned BeginLabel, unsigned EndLabel) {
-  LandingPadInfo &UI = getOrCreateLandingPadInfo(LandingPad);
-  if (!UI.BeginLabel) UI.BeginLabel = BeginLabel;  
-  UI.EndLabel = EndLabel;  
+  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
+  LP.BeginLabels.push_back(BeginLabel);
+  LP.EndLabels.push_back(EndLabel);
 }
 
 /// addLandingPad - Provide the label of a try LandingPad block.
 ///
 unsigned MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) {
   unsigned LandingPadLabel = NextLabelID();
-  LandingPadInfo &UI = getOrCreateLandingPadInfo(LandingPad);
-  UI.LandingPadLabel = LandingPadLabel;  
+  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
+  LP.LandingPadLabel = LandingPadLabel;  
   return LandingPadLabel;
 }
 
@@ -1684,35 +1696,85 @@ unsigned MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) {
 /// information.
 void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad,
                                        Function *Personality) {
-  LandingPadInfo &UI = getOrCreateLandingPadInfo(LandingPad);
-  UI.Personality = Personality;
+  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
+  LP.Personality = Personality;
+
+  for (unsigned i = 0; i < Personalities.size(); ++i)
+    if (Personalities[i] == Personality)
+      return;
+  
+  Personalities.push_back(Personality);
 }
 
 /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
 ///
 void MachineModuleInfo::addCatchTypeInfo(MachineBasicBlock *LandingPad,
                                         std::vector<GlobalVariable *> &TyInfo) {
-  LandingPadInfo &UI = getOrCreateLandingPadInfo(LandingPad);
+  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
   for (unsigned N = TyInfo.size(); N; --N)
-    UI.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
+    LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
+}
+
+/// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
+///
+void MachineModuleInfo::addFilterTypeInfo(MachineBasicBlock *LandingPad,
+                                        std::vector<GlobalVariable *> &TyInfo) {
+  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
+  std::vector<unsigned> IdsInFilter (TyInfo.size());
+  for (unsigned I = 0, E = TyInfo.size(); I != E; ++I)
+    IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
+  LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
+}
+
+/// addCleanup - Add a cleanup action for a landing pad.
+///
+void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
+  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
+  LP.TypeIds.push_back(0);
 }
-                        
+
 /// TidyLandingPads - Remap landing pad labels and remove any deleted landing
 /// pads.
 void MachineModuleInfo::TidyLandingPads() {
   for (unsigned i = 0; i != LandingPads.size(); ) {
     LandingPadInfo &LandingPad = LandingPads[i];
-    LandingPad.BeginLabel = MappedLabel(LandingPad.BeginLabel);
-    LandingPad.EndLabel = MappedLabel(LandingPad.EndLabel);
     LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel);
-    
-    if (!LandingPad.BeginLabel ||
-        !LandingPad.EndLabel ||
-        !LandingPad.LandingPadLabel) {
+
+    // Special case: we *should* emit LPs with null LP MBB. This indicates
+    // "rethrow" case.
+    if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
       LandingPads.erase(LandingPads.begin() + i);
       continue;
     }
-    
+
+    for (unsigned j=0; j != LandingPads[i].BeginLabels.size(); ) {
+      unsigned BeginLabel = MappedLabel(LandingPad.BeginLabels[j]);
+      unsigned EndLabel = MappedLabel(LandingPad.EndLabels[j]);
+
+
+      if (!BeginLabel || !EndLabel) {
+        LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
+        LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
+        continue;
+      }
+
+      LandingPad.BeginLabels[j] = BeginLabel;
+      LandingPad.EndLabels[j] = EndLabel;
+      ++j;
+    }
+
+    // Remove landing pads with no try-ranges.
+    if (!LandingPads[i].BeginLabels.size()) {
+      LandingPads.erase(LandingPads.begin() + i);
+      continue;
+    }
+
+    // If there is no landing pad, ensure that the list of typeids is empty.
+    // If the only typeid is a cleanup, this is the same as having no typeids.
+    if (!LandingPad.LandingPadBlock ||
+        (LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0]))
+      LandingPad.TypeIds.clear();
+
     ++i;
   }
 }
@@ -1727,12 +1789,65 @@ unsigned MachineModuleInfo::getTypeIDFor(GlobalVariable *TI) {
   return TypeInfos.size();
 }
 
-/// getLandingPadInfos - Return a reference to the landing pad info for the
-/// current function.
+/// getFilterIDFor - Return the filter id for the specified typeinfos.  This is
+/// function wide.
+int MachineModuleInfo::getFilterIDFor(std::vector<unsigned> &TyIds) {
+  // If the new filter coincides with the tail of an existing filter, then
+  // re-use the existing filter.  Folding filters more than this requires
+  // re-ordering filters and/or their elements - probably not worth it.
+  for (std::vector<unsigned>::iterator I = FilterEnds.begin(),
+       E = FilterEnds.end(); I != E; ++I) {
+    unsigned i = *I, j = TyIds.size();
+
+    while (i && j)
+      if (FilterIds[--i] != TyIds[--j])
+        goto try_next;
+
+    if (!j)
+      // The new filter coincides with range [i, end) of the existing filter.
+      return -(1 + i);
+
+try_next:;
+  }
+
+  // Add the new filter.
+  int FilterID = -(1 + FilterIds.size());
+  FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
+  for (unsigned I = 0, N = TyIds.size(); I != N; ++I)
+    FilterIds.push_back(TyIds[I]);
+  FilterEnds.push_back(FilterIds.size());
+  FilterIds.push_back(0); // terminator
+  return FilterID;
+}
+
+/// getPersonality - Return the personality function for the current function.
 Function *MachineModuleInfo::getPersonality() const {
+  // FIXME: Until PR1414 will be fixed, we're using 1 personality function per
+  // function
   return !LandingPads.empty() ? LandingPads[0].Personality : NULL;
 }
 
+/// getPersonalityIndex - Return unique index for current personality
+/// function. NULL personality function should always get zero index.
+unsigned MachineModuleInfo::getPersonalityIndex() const {
+  const Function* Personality = NULL;
+  
+  // Scan landing pads. If there is at least one non-NULL personality - use it.
+  for (unsigned i = 0; i != LandingPads.size(); ++i)
+    if (LandingPads[i].Personality) {
+      Personality = LandingPads[i].Personality;
+      break;
+    }
+  
+  for (unsigned i = 0; i < Personalities.size(); ++i) {
+    if (Personalities[i] == Personality)
+      return i;
+  }
+
+  // This should never happen
+  assert(0 && "Personality function should be set!");
+  return 0;
+}
 
 //===----------------------------------------------------------------------===//
 /// DebugLabelFolding pass - This pass prunes out redundant labels.  This allows
@@ -1742,10 +1857,15 @@ Function *MachineModuleInfo::getPersonality() const {
 namespace llvm {
 
 struct DebugLabelFolder : public MachineFunctionPass {
+  static char ID;
+  DebugLabelFolder() : MachineFunctionPass((intptr_t)&ID) {}
+
   virtual bool runOnMachineFunction(MachineFunction &MF);
   virtual const char *getPassName() const { return "Label Folder"; }
 };
 
+char DebugLabelFolder::ID = 0;
+
 bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) {
   // Get machine module info.
   MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>();