Handle load/store of misaligned vectors that are the
[oota-llvm.git] / lib / CodeGen / MachineModuleInfo.cpp
index d4d132989ec73470a9767f7688265ee9759677e9..6d285bde049ba7b5ac547fe87fcfba96899c447f 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by James M. Laskey and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 
@@ -104,6 +104,12 @@ static GlobalVariable *getGlobalVariable(Value *V) {
   } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
     if (CE->getOpcode() == Instruction::BitCast) {
       return dyn_cast<GlobalVariable>(CE->getOperand(0));
+    } else if (CE->getOpcode() == Instruction::GetElementPtr) {
+      for (unsigned int i=1; i<CE->getNumOperands(); i++) {
+        if (!CE->getOperand(i)->isNullValue())
+          return NULL;
+      }
+      return dyn_cast<GlobalVariable>(CE->getOperand(0));
     }
   }
   return NULL;
@@ -117,6 +123,12 @@ static bool isGlobalVariable(Value *V) {
   } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
     if (CE->getOpcode() == Instruction::BitCast) {
       return isa<GlobalVariable>(CE->getOperand(0));
+    } else if (CE->getOpcode() == Instruction::GetElementPtr) {
+      for (unsigned int i=1; i<CE->getNumOperands(); i++) {
+        if (!CE->getOperand(i)->isNullValue())
+          return false;
+      }
+      return isa<GlobalVariable>(CE->getOperand(0));
     }
   }
   return false;
@@ -1262,7 +1274,7 @@ const PointerType *DISerializer::getStrPtrType() {
   // If not already defined.
   if (!StrPtrTy) {
     // Construct the pointer to signed bytes.
-    StrPtrTy = PointerType::get(Type::Int8Ty);
+    StrPtrTy = PointerType::getUnqual(Type::Int8Ty);
   }
   
   return StrPtrTy;
@@ -1277,7 +1289,7 @@ const PointerType *DISerializer::getEmptyStructPtrType() {
     const StructType *EmptyStructTy =
                                     StructType::get(std::vector<const Type*>());
     // Construct the pointer to empty structure type.
-    EmptyStructPtrTy = PointerType::get(EmptyStructTy);
+    EmptyStructPtrTy = PointerType::getUnqual(EmptyStructTy);
   }
   
   return EmptyStructPtrTy;
@@ -1364,6 +1376,12 @@ GlobalVariable *DISerializer::Serialize(DebugInfoDesc *DD) {
   return GV;
 }
 
+/// addDescriptor - Directly connect DD with existing GV.
+void DISerializer::addDescriptor(DebugInfoDesc *DD,
+                                 GlobalVariable *GV) {
+  DescGlobals[DD] = GV;
+}
+
 //===----------------------------------------------------------------------===//
 
 /// Verify - Return true if the GlobalVariable appears to be a valid
@@ -1453,6 +1471,14 @@ bool DIVerifier::Verify(GlobalVariable *GV) {
   return true;
 }
 
+/// isVerified - Return true if the specified GV has already been
+/// verified as a debug information descriptor.
+bool DIVerifier::isVerified(GlobalVariable *GV) {
+  unsigned &ValiditySlot = Validity[GV];
+  if (ValiditySlot) return ValiditySlot == Valid;
+  return false;
+}
+
 //===----------------------------------------------------------------------===//
 
 DebugScope::~DebugScope() {
@@ -1476,6 +1502,8 @@ MachineModuleInfo::MachineModuleInfo()
 , FrameMoves()
 , LandingPads()
 , Personalities()
+, CallsEHReturn(0)
+, CallsUnwindInit(0)
 {
   // Always emit "no personality" info
   Personalities.push_back(NULL);
@@ -1521,6 +1549,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.
@@ -1530,16 +1562,25 @@ DebugInfoDesc *MachineModuleInfo::getDescFor(Value *V) {
   return DR.Deserialize(V);
 }
 
-/// Verify - Verify that a Value is debug information descriptor.
-///
-bool MachineModuleInfo::Verify(Value *V) {
-  return VR.Verify(V);
-}
-
 /// AnalyzeModule - Scan the module for global debug information.
 ///
 void MachineModuleInfo::AnalyzeModule(Module &M) {
   SetupCompileUnits(M);
+
+  // Insert functions in the llvm.used array into UsedFunctions.
+  GlobalVariable *GV = M.getGlobalVariable("llvm.used");
+  if (!GV || !GV->hasInitializer()) return;
+
+  // Should be an array of 'i8*'.
+  ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
+  if (InitList == 0) return;
+
+  for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
+    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(InitList->getOperand(i)))
+      if (CE->getOpcode() == Instruction::BitCast)
+        if (Function *F = dyn_cast<Function>(CE->getOperand(0)))
+          UsedFunctions.insert(F);
+  }
 }
 
 /// needsFrameInfo - Returns true if we need to gather callee-saved register
@@ -1572,11 +1613,11 @@ MachineModuleInfo::getGlobalVariablesUsing(Module &M,
   return ::getGlobalVariablesUsing(M, RootName);
 }
 
-/// RecordLabel - Records location information and associates it with a
+/// RecordSourceLine - Records location information and associates it with a
 /// debug label.  Returns a unique label ID used to generate a label and 
 /// provide correspondence to the source line list.
-unsigned MachineModuleInfo::RecordLabel(unsigned Line, unsigned Column,
-                                       unsigned Source) {
+unsigned MachineModuleInfo::RecordSourceLine(unsigned Line, unsigned Column,
+                                             unsigned Source) {
   unsigned ID = NextLabelID();
   Lines.push_back(SourceLineInfo(Line, Column, Source, ID));
   return ID;
@@ -1618,8 +1659,8 @@ unsigned MachineModuleInfo::RecordRegionEnd(Value *V) {
 
 /// RecordVariable - Indicate the declaration of  a local variable.
 ///
-void MachineModuleInfo::RecordVariable(Value *V, unsigned FrameIndex) {
-  VariableDesc *VD = cast<VariableDesc>(DR.Deserialize(V));
+void MachineModuleInfo::RecordVariable(GlobalValue *GV, unsigned FrameIndex) {
+  VariableDesc *VD = cast<VariableDesc>(DR.Deserialize(GV));
   DebugScope *Scope = getOrCreateScope(VD->getContext());
   DebugVariable *DV = new DebugVariable(VD, FrameIndex);
   Scope->AddVariable(DV);
@@ -1708,12 +1749,23 @@ void MachineModuleInfo::addCatchTypeInfo(MachineBasicBlock *LandingPad,
   for (unsigned N = TyInfo.size(); N; --N)
     LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
 }
-                        
-/// setIsFilterLandingPad - Indicates that the landing pad is a throw filter.
+
+/// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
 ///
-void MachineModuleInfo::setIsFilterLandingPad(MachineBasicBlock *LandingPad) {
+void MachineModuleInfo::addFilterTypeInfo(MachineBasicBlock *LandingPad,
+                                        std::vector<GlobalVariable *> &TyInfo) {
   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
-  LP.IsFilter = true;
+  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
@@ -1723,16 +1775,17 @@ void MachineModuleInfo::TidyLandingPads() {
     LandingPadInfo &LandingPad = LandingPads[i];
     LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel);
 
-    if (!LandingPad.LandingPadLabel) {
+    // Special case: we *should* emit LPs with null LP MBB. This indicates
+    // "nounwind" 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);
@@ -1743,7 +1796,19 @@ void MachineModuleInfo::TidyLandingPads() {
       LandingPad.EndLabels[j] = EndLabel;
       ++j;
     }
-    
+
+    // Remove landing pads with no try-ranges.
+    if (LandingPads[i].BeginLabels.empty()) {
+      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;
   }
 }
@@ -1758,6 +1823,37 @@ unsigned MachineModuleInfo::getTypeIDFor(GlobalVariable *TI) {
   return TypeInfos.size();
 }
 
+/// 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
@@ -1768,9 +1864,15 @@ Function *MachineModuleInfo::getPersonality() const {
 /// getPersonalityIndex - Return unique index for current personality
 /// function. NULL personality function should always get zero index.
 unsigned MachineModuleInfo::getPersonalityIndex() const {
-  const Function* Personality = (!LandingPads.empty() ?
-                                 LandingPads[0].Personality : NULL);
-
+  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;
@@ -1802,9 +1904,6 @@ bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) {
   // Get machine module info.
   MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>();
   if (!MMI) return false;
-  // Get target instruction info.
-  const TargetInstrInfo *TII = MF.getTarget().getInstrInfo();
-  if (!TII) return false;
   
   // Track if change is made.
   bool MadeChange = false;
@@ -1817,7 +1916,7 @@ bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) {
     // Iterate through instructions.
     for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
       // Is it a label.
-      if ((unsigned)I->getOpcode() == TargetInstrInfo::LABEL) {
+      if (I->isDebugLabel()) {
         // The label ID # is always operand #0, an immediate.
         unsigned NextLabel = I->getOperand(0).getImm();