Implement Jakob's suggestion on how to detect fall thought without calling
[oota-llvm.git] / lib / CodeGen / AsmPrinter / AsmPrinter.cpp
index d8a7ac3b44ed07213ea6416e2f8b77aaa840d69f..187963c26a1ffeed2e1f351093da42a70b1ecf31 100644 (file)
@@ -199,6 +199,9 @@ bool AsmPrinter::doInitialization(Module &M) {
   case ExceptionHandling::ARM:
     DE = new ARMException(this);
     return false;
+  case ExceptionHandling::Win64:
+    DE = new Win64Exception(this);
+    return false;
   }
 
   llvm_unreachable("Unknown exception type.");
@@ -266,7 +269,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
   }
 
   MCSymbol *GVSym = Mang->getSymbol(GV);
-  EmitVisibility(GVSym, GV->getVisibility());
+  EmitVisibility(GVSym, GV->getVisibility(), !GV->isDeclaration());
 
   if (!GV->hasInitializer())   // External globals require no extra code.
     return;
@@ -601,6 +604,11 @@ AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() {
   return CFI_M_None;
 }
 
+bool AsmPrinter::needsSEHMoves() {
+  return MAI->getExceptionHandlingType() == ExceptionHandling::Win64 &&
+    MF->getFunction()->needsUnwindTableEntry();
+}
+
 void AsmPrinter::emitPrologLabel(const MachineInstr &MI) {
   MCSymbol *Label = MI.getOperand(0).getMCSymbol();
 
@@ -766,7 +774,7 @@ void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const {
   int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
 
   for (const unsigned *SR = TRI->getSuperRegisters(MLoc.getReg());
-       *SR && Reg == -1; ++SR) {
+       *SR && Reg < 0; ++SR) {
     Reg = TRI->getDwarfRegNum(*SR, false);
     // FIXME: Get the bit range this register uses of the superregister
     // so that we can produce a DW_OP_bit_piece
@@ -1917,7 +1925,7 @@ isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
     return false;
 
   // The predecessor has to be immediately before this block.
-  const MachineBasicBlock *Pred = *PI;
+  MachineBasicBlock *Pred = *PI;
 
   if (!Pred->isLayoutSuccessor(MBB))
     return false;
@@ -1926,9 +1934,26 @@ isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
   if (Pred->empty())
     return true;
 
-  // Otherwise, check the last instruction.
-  const MachineInstr &LastInst = Pred->back();
-  return !LastInst.getDesc().isBarrier();
+  // Check the terminators in the previous blocks
+  for (MachineBasicBlock::iterator II = Pred->getFirstTerminator(),
+         IE = Pred->end(); II != IE; ++II) {
+    MachineInstr &MI = *II;
+
+    // If it is not a simple branch, we are in a table somewhere.
+    if (!MI.getDesc().isBranch() || MI.getDesc().isIndirectBranch())
+      return false;
+
+    // If we are the operands of one of the branches, this is not
+    // a fall through.
+    for (MachineInstr::mop_iterator OI = MI.operands_begin(),
+           OE = MI.operands_end(); OI != OE; ++OI) {
+      const MachineOperand& OP = *OI;
+      if (OP.isMBB() && OP.getMBB() == MBB)
+        return false;
+    }
+  }
+
+  return true;
 }