Partial implementation of calling functions with byval arguments:
[oota-llvm.git] / lib / CodeGen / SelectionDAG / SelectionDAGISel.cpp
index 4dadde0dfe58d8b15e3025986a9dfbe0429eda14..78539d454ed7780f24c8d22c86ff9897b4da53f2 100644 (file)
@@ -73,9 +73,9 @@ MachinePassRegistry RegisterScheduler::Registry;
 namespace {
   cl::opt<RegisterScheduler::FunctionPassCtor, false,
           RegisterPassParser<RegisterScheduler> >
-  ISHeuristic("sched",
+  ISHeuristic("pre-RA-sched",
               cl::init(&createDefaultScheduler),
-              cl::desc("Instruction schedulers available:"));
+              cl::desc("Instruction schedulers available (before register allocation):"));
 
   static RegisterScheduler
   defaultListDAGScheduler("default", "  Best scheduler for the target",
@@ -205,12 +205,11 @@ namespace llvm {
   };
 }
 
-/// isFilterOrSelector - Return true if this instruction is a call to the
-/// eh.filter or the eh.selector intrinsic.
-static bool isFilterOrSelector(Instruction *I) {
+/// isSelector - Return true if this instruction is a call to the
+/// eh.selector intrinsic.
+static bool isSelector(Instruction *I) {
   if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
-    return II->getIntrinsicID() == Intrinsic::eh_selector
-      || II->getIntrinsicID() == Intrinsic::eh_filter;
+    return II->getIntrinsicID() == Intrinsic::eh_selector;
   return false;
 }
 
@@ -614,6 +613,195 @@ public:
 };
 } // end namespace llvm
 
+
+/// getCopyFromParts - Create a value that contains the
+/// specified legal parts combined into the value they represent.
+static SDOperand getCopyFromParts(SelectionDAG &DAG,
+                                  const SDOperand *Parts,
+                                  unsigned NumParts,
+                                  MVT::ValueType PartVT,
+                                  MVT::ValueType ValueVT,
+                                  ISD::NodeType AssertOp = ISD::DELETED_NODE) {
+  if (!MVT::isVector(ValueVT) || NumParts == 1) {
+    SDOperand Val = Parts[0];
+
+    // If the value was expanded, copy from the top part.
+    if (NumParts > 1) {
+      assert(NumParts == 2 &&
+             "Cannot expand to more than 2 elts yet!");
+      SDOperand Hi = Parts[1];
+      if (!DAG.getTargetLoweringInfo().isLittleEndian())
+        std::swap(Val, Hi);
+      return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Val, Hi);
+    }
+
+    // Otherwise, if the value was promoted or extended, truncate it to the
+    // appropriate type.
+    if (PartVT == ValueVT)
+      return Val;
+  
+    if (MVT::isVector(PartVT)) {
+      assert(MVT::isVector(ValueVT) && "Unknown vector conversion!");
+      return DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+    }
+  
+    if (MVT::isInteger(PartVT) &&
+        MVT::isInteger(ValueVT)) {
+      if (ValueVT < PartVT) {
+        // For a truncate, see if we have any information to
+        // indicate whether the truncated bits will always be
+        // zero or sign-extension.
+        if (AssertOp != ISD::DELETED_NODE)
+          Val = DAG.getNode(AssertOp, PartVT, Val,
+                            DAG.getValueType(ValueVT));
+        return DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
+      } else {
+        return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
+      }
+    }
+  
+    if (MVT::isFloatingPoint(PartVT) &&
+        MVT::isFloatingPoint(ValueVT))
+      return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
+
+    if (MVT::getSizeInBits(PartVT) == 
+        MVT::getSizeInBits(ValueVT))
+      return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
+
+    assert(0 && "Unknown mismatch!");
+  }
+
+  // Handle a multi-element vector.
+  MVT::ValueType IntermediateVT, RegisterVT;
+  unsigned NumIntermediates;
+  unsigned NumRegs =
+    DAG.getTargetLoweringInfo()
+      .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
+                              RegisterVT);
+
+  assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
+  assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
+  assert(RegisterVT == Parts[0].getValueType() &&
+         "Part type doesn't match part!");
+
+  // Assemble the parts into intermediate operands.
+  SmallVector<SDOperand, 8> Ops(NumIntermediates);
+  if (NumIntermediates == NumParts) {
+    // If the register was not expanded, truncate or copy the value,
+    // as appropriate.
+    for (unsigned i = 0; i != NumParts; ++i)
+      Ops[i] = getCopyFromParts(DAG, &Parts[i], 1,
+                                PartVT, IntermediateVT);
+  } else if (NumParts > 0) {
+    // If the intermediate type was expanded, build the intermediate operands
+    // from the parts.
+    assert(NumParts % NumIntermediates == 0 &&
+           "Must expand into a divisible number of parts!");
+    unsigned Factor = NumParts / NumIntermediates;
+    for (unsigned i = 0; i != NumIntermediates; ++i)
+      Ops[i] = getCopyFromParts(DAG, &Parts[i * Factor], Factor,
+                                PartVT, IntermediateVT);
+  }
+  
+  // Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the intermediate
+  // operands.
+  return DAG.getNode(MVT::isVector(IntermediateVT) ?
+                       ISD::CONCAT_VECTORS :
+                       ISD::BUILD_VECTOR,
+                     ValueVT, &Ops[0], NumIntermediates);
+}
+
+/// getCopyToParts - Create a series of nodes that contain the
+/// specified value split into legal parts.
+static void getCopyToParts(SelectionDAG &DAG,
+                           SDOperand Val,
+                           SDOperand *Parts,
+                           unsigned NumParts,
+                           MVT::ValueType PartVT) {
+  TargetLowering &TLI = DAG.getTargetLoweringInfo();
+  MVT::ValueType PtrVT = TLI.getPointerTy();
+  MVT::ValueType ValueVT = Val.getValueType();
+
+  if (!MVT::isVector(ValueVT) || NumParts == 1) {
+    // If the value was expanded, copy from the parts.
+    if (NumParts > 1) {
+      for (unsigned i = 0; i != NumParts; ++i)
+        Parts[i] = DAG.getNode(ISD::EXTRACT_ELEMENT, PartVT, Val,
+                               DAG.getConstant(i, PtrVT));
+      if (!DAG.getTargetLoweringInfo().isLittleEndian())
+        std::reverse(Parts, Parts + NumParts);
+      return;
+    }
+
+    // If there is a single part and the types differ, this must be
+    // a promotion.
+    if (PartVT != ValueVT) {
+      if (MVT::isVector(PartVT)) {
+        assert(MVT::isVector(ValueVT) &&
+               "Not a vector-vector cast?");
+        Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+      } else if (MVT::isInteger(PartVT) && MVT::isInteger(ValueVT)) {
+        if (PartVT < ValueVT)
+          Val = DAG.getNode(ISD::TRUNCATE, PartVT, Val);
+        else
+          Val = DAG.getNode(ISD::ANY_EXTEND, PartVT, Val);
+      } else if (MVT::isFloatingPoint(PartVT) &&
+                 MVT::isFloatingPoint(ValueVT)) {
+        Val = DAG.getNode(ISD::FP_EXTEND, PartVT, Val);
+      } else if (MVT::getSizeInBits(PartVT) == 
+                 MVT::getSizeInBits(ValueVT)) {
+        Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+      } else {
+        assert(0 && "Unknown mismatch!");
+      }
+    }
+    Parts[0] = Val;
+    return;
+  }
+
+  // Handle a multi-element vector.
+  MVT::ValueType IntermediateVT, RegisterVT;
+  unsigned NumIntermediates;
+  unsigned NumRegs =
+    DAG.getTargetLoweringInfo()
+      .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
+                              RegisterVT);
+  unsigned NumElements = MVT::getVectorNumElements(ValueVT);
+
+  assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
+  assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
+
+  // Split the vector into intermediate operands.
+  SmallVector<SDOperand, 8> Ops(NumIntermediates);
+  for (unsigned i = 0; i != NumIntermediates; ++i)
+    if (MVT::isVector(IntermediateVT))
+      Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR,
+                           IntermediateVT, Val,
+                           DAG.getConstant(i * (NumElements / NumIntermediates),
+                                           PtrVT));
+    else
+      Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
+                           IntermediateVT, Val, 
+                           DAG.getConstant(i, PtrVT));
+
+  // Split the intermediate operands into legal parts.
+  if (NumParts == NumIntermediates) {
+    // If the register was not expanded, promote or copy the value,
+    // as appropriate.
+    for (unsigned i = 0; i != NumParts; ++i)
+      getCopyToParts(DAG, Ops[i], &Parts[i], 1, PartVT);
+  } else if (NumParts > 0) {
+    // If the intermediate type was expanded, split each the value into
+    // legal parts.
+    assert(NumParts % NumIntermediates == 0 &&
+           "Must expand into a divisible number of parts!");
+    unsigned Factor = NumParts / NumIntermediates;
+    for (unsigned i = 0; i != NumIntermediates; ++i)
+      getCopyToParts(DAG, Ops[i], &Parts[i * Factor], Factor, PartVT);
+  }
+}
+
+
 SDOperand SelectionDAGLowering::getValue(const Value *V) {
   SDOperand &N = NodeMap[V];
   if (N.Val) return N;
@@ -654,13 +842,13 @@ SDOperand SelectionDAGLowering::getValue(const Value *V) {
       
       // Now that we know the number and type of the elements, push a
       // Constant or ConstantFP node onto the ops list for each element of
-      // the packed constant.
+      // the vector constant.
       SmallVector<SDOperand, 8> Ops;
       if (ConstantVector *CP = dyn_cast<ConstantVector>(C)) {
         for (unsigned i = 0; i != NumElements; ++i)
           Ops.push_back(getValue(CP->getOperand(i)));
       } else {
-        assert(isa<ConstantAggregateZero>(C) && "Unknown packed constant!");
+        assert(isa<ConstantAggregateZero>(C) && "Unknown vector constant!");
         SDOperand Op;
         if (MVT::isFloatingPoint(PVT))
           Op = DAG.getConstantFP(0, PVT);
@@ -714,8 +902,8 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
     SDOperand RetOp = getValue(I.getOperand(i));
     
     // If this is an integer return value, we need to promote it ourselves to
-    // the full width of a register, since LegalizeOp will use ANY_EXTEND rather
-    // than sign/zero.
+    // the full width of a register, since getCopyToParts and Legalize will use
+    // ANY_EXTEND rather than sign/zero.
     // FIXME: C calling convention requires the return type to be promoted to
     // at least 32-bit. But this is not necessary for non-C calling conventions.
     if (MVT::isInteger(RetOp.getValueType()) && 
@@ -733,9 +921,19 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
       if (Attrs && Attrs->paramHasAttr(0, ParamAttr::ZExt))
         ExtendKind = ISD::ZERO_EXTEND;
       RetOp = DAG.getNode(ExtendKind, TmpVT, RetOp);
+      NewValues.push_back(RetOp);
+      NewValues.push_back(DAG.getConstant(false, MVT::i32));
+    } else {
+      MVT::ValueType VT = RetOp.getValueType();
+      unsigned NumParts = TLI.getNumRegisters(VT);
+      MVT::ValueType PartVT = TLI.getRegisterType(VT);
+      SmallVector<SDOperand, 4> Parts(NumParts);
+      getCopyToParts(DAG, RetOp, &Parts[0], NumParts, PartVT);
+      for (unsigned i = 0; i < NumParts; ++i) {
+        NewValues.push_back(Parts[i]);
+        NewValues.push_back(DAG.getConstant(false, MVT::i32));
+      }
     }
-    NewValues.push_back(RetOp);
-    NewValues.push_back(DAG.getConstant(false, MVT::i32));
   }
   DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other,
                           &NewValues[0], NewValues.size()));
@@ -2131,21 +2329,21 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) {
   AllocSize = DAG.getNode(ISD::MUL, IntPtr, AllocSize,
                           getIntPtrConstant(TySize));
 
-  // Handle alignment.  If the requested alignment is less than or equal to the
-  // stack alignment, ignore it and round the size of the allocation up to the
-  // stack alignment size.  If the size is greater than the stack alignment, we
-  // note this in the DYNAMIC_STACKALLOC node.
+  // Handle alignment.  If the requested alignment is less than or equal to
+  // the stack alignment, ignore it.  If the size is greater than or equal to
+  // the stack alignment, we note this in the DYNAMIC_STACKALLOC node.
   unsigned StackAlign =
     TLI.getTargetMachine().getFrameInfo()->getStackAlignment();
-  if (Align <= StackAlign) {
+  if (Align <= StackAlign)
     Align = 0;
-    // Add SA-1 to the size.
-    AllocSize = DAG.getNode(ISD::ADD, AllocSize.getValueType(), AllocSize,
-                            getIntPtrConstant(StackAlign-1));
-    // Mask out the low bits for alignment purposes.
-    AllocSize = DAG.getNode(ISD::AND, AllocSize.getValueType(), AllocSize,
-                            getIntPtrConstant(~(uint64_t)(StackAlign-1)));
-  }
+
+  // Round the size of the allocation up to the stack alignment size
+  // by add SA-1 to the size.
+  AllocSize = DAG.getNode(ISD::ADD, AllocSize.getValueType(), AllocSize,
+                          getIntPtrConstant(StackAlign-1));
+  // Mask out the low bits for alignment purposes.
+  AllocSize = DAG.getNode(ISD::AND, AllocSize.getValueType(), AllocSize,
+                          getIntPtrConstant(~(uint64_t)(StackAlign-1)));
 
   SDOperand Ops[] = { getRoot(), AllocSize, getIntPtrConstant(Align) };
   const MVT::ValueType *VTs = DAG.getNodeValueTypes(AllocSize.getValueType(),
@@ -2293,26 +2491,17 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I,
   }
 }
 
-/// ExtractGlobalVariable - If C is a global variable, or a bitcast of one
-/// (possibly constant folded), return it.  Otherwise return NULL.
-static GlobalVariable *ExtractGlobalVariable (Constant *C) {
-  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C))
-    return GV;
-  else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
-    if (CE->getOpcode() == Instruction::BitCast)
-      return dyn_cast<GlobalVariable>(CE->getOperand(0));
-    else if (CE->getOpcode() == Instruction::GetElementPtr) {
-      for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
-        if (!CE->getOperand(i)->isNullValue())
-          return NULL;
-      return dyn_cast<GlobalVariable>(CE->getOperand(0));
-    }
-  }
-  return NULL;
+/// ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
+static GlobalVariable *ExtractTypeInfo (Value *V) {
+  V = IntrinsicInst::StripPointerCasts(V);
+  GlobalVariable *GV = dyn_cast<GlobalVariable>(V);
+  assert (GV || isa<ConstantPointerNull>(V) &&
+          "TypeInfo must be a global variable or NULL");
+  return GV;
 }
 
 /// addCatchInfo - Extract the personality and type infos from an eh.selector
-/// or eh.filter call, and add them to the specified machine basic block.
+/// call, and add them to the specified machine basic block.
 static void addCatchInfo(CallInst &I, MachineModuleInfo *MMI,
                          MachineBasicBlock *MBB) {
   // Inform the MachineModuleInfo of the personality for this landing pad.
@@ -2325,36 +2514,38 @@ static void addCatchInfo(CallInst &I, MachineModuleInfo *MMI,
   // Gather all the type infos for this landing pad and pass them along to
   // MachineModuleInfo.
   std::vector<GlobalVariable *> TyInfo;
-  for (unsigned i = 3, N = I.getNumOperands(); i < N; ++i) {
-    Constant *C = cast<Constant>(I.getOperand(i));
-    GlobalVariable *GV = ExtractGlobalVariable(C);
-    assert (GV || isa<ConstantPointerNull>(C) &&
-            "TypeInfo must be a global variable or NULL");
-    TyInfo.push_back(GV);
-  }
-  if (I.getCalledFunction()->getIntrinsicID() == Intrinsic::eh_filter)
-    MMI->addFilterTypeInfo(MBB, TyInfo);
-  else
-    MMI->addCatchTypeInfo(MBB, TyInfo);
-}
+  unsigned N = I.getNumOperands();
+
+  for (unsigned i = N - 1; i > 2; --i) {
+    if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(i))) {
+      unsigned FilterLength = CI->getZExtValue();
+      unsigned FirstCatch = i + FilterLength + 1;
+      assert (FirstCatch <= N && "Invalid filter length");
+
+      if (FirstCatch < N) {
+        TyInfo.reserve(N - FirstCatch);
+        for (unsigned j = FirstCatch; j < N; ++j)
+          TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
+        MMI->addCatchTypeInfo(MBB, TyInfo);
+        TyInfo.clear();
+      }
 
-/// propagateEHRegister - The specified EH register is required in a successor
-/// of the EH landing pad. Propagate it (by adding it to livein) to all the
-/// blocks in the paths between the landing pad and the specified block.
-static void propagateEHRegister(MachineBasicBlock *MBB, unsigned EHReg,
-                                SmallPtrSet<MachineBasicBlock*, 8> Visited) {
-  if (MBB->isLandingPad() || !Visited.insert(MBB))
-    return;
+      TyInfo.reserve(FilterLength);
+      for (unsigned j = i + 1; j < FirstCatch; ++j)
+        TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
+      MMI->addFilterTypeInfo(MBB, TyInfo);
+      TyInfo.clear();
 
-  MBB->addLiveIn(EHReg);
-  for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
-         E = MBB->pred_end(); PI != E; ++PI)
-    propagateEHRegister(*PI, EHReg, Visited);
-}
+      N = i;
+    }
+  }
 
-static void propagateEHRegister(MachineBasicBlock *MBB, unsigned EHReg) {
-  SmallPtrSet<MachineBasicBlock*, 8> Visited;
-  propagateEHRegister(MBB, EHReg, Visited);
+  if (N > 3) {
+    TyInfo.reserve(N - 3);
+    for (unsigned j = 3; j < N; ++j)
+      TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
+    MMI->addCatchTypeInfo(MBB, TyInfo);
+  }
 }
 
 /// visitIntrinsicCall - Lower the call to the specified intrinsic function.  If
@@ -2467,9 +2658,11 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     
   case Intrinsic::eh_exception: {
     if (ExceptionHandling) {
-      if (!CurMBB->isLandingPad() && TLI.getExceptionAddressRegister())
-          propagateEHRegister(CurMBB, TLI.getExceptionAddressRegister());
-
+      if (!CurMBB->isLandingPad()) {
+        // FIXME: Mark exception register as live in.  Hack for PR1508.
+        unsigned Reg = TLI.getExceptionAddressRegister();
+        if (Reg) CurMBB->addLiveIn(Reg);
+      }
       // Insert the EXCEPTIONADDR instruction.
       SDVTList VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other);
       SDOperand Ops[1];
@@ -2483,8 +2676,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     return 0;
   }
 
-  case Intrinsic::eh_selector:
-  case Intrinsic::eh_filter:{
+  case Intrinsic::eh_selector:{
     MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
 
     if (ExceptionHandling && MMI) {
@@ -2494,8 +2686,9 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
 #ifndef NDEBUG
         FuncInfo.CatchInfoLost.insert(&I);
 #endif
-        if (TLI.getExceptionSelectorRegister())
-          propagateEHRegister(CurMBB, TLI.getExceptionSelectorRegister());
+        // FIXME: Mark exception selector register as live in.  Hack for PR1508.
+        unsigned Reg = TLI.getExceptionSelectorRegister();
+        if (Reg) CurMBB->addLiveIn(Reg);
       }
 
       // Insert the EHSELECTION instruction.
@@ -2518,20 +2711,65 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     
     if (MMI) {
       // Find the type id for the given typeinfo.
-      Constant *C = cast<Constant>(I.getOperand(1));
-      GlobalVariable *GV = ExtractGlobalVariable(C);
-      assert (GV || isa<ConstantPointerNull>(C) &&
-              "TypeInfo must be a global variable or NULL");
+      GlobalVariable *GV = ExtractTypeInfo(I.getOperand(1));
 
       unsigned TypeID = MMI->getTypeIDFor(GV);
       setValue(&I, DAG.getConstant(TypeID, MVT::i32));
     } else {
-      setValue(&I, DAG.getConstant(0, MVT::i32));
+      // Return something different to eh_selector.
+      setValue(&I, DAG.getConstant(1, MVT::i32));
     }
 
     return 0;
   }
 
+  case Intrinsic::eh_return: {
+    MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+
+    if (MMI && ExceptionHandling) {
+      MMI->setCallsEHReturn(true);
+      DAG.setRoot(DAG.getNode(ISD::EH_RETURN,
+                              MVT::Other,
+                              getRoot(),
+                              getValue(I.getOperand(1)),
+                              getValue(I.getOperand(2))));
+    } else {
+      setValue(&I, DAG.getConstant(0, TLI.getPointerTy()));
+    }
+
+    return 0;
+  }
+
+   case Intrinsic::eh_unwind_init: {    
+     if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo()) {
+       MMI->setCallsUnwindInit(true);
+     }
+
+     return 0;
+   }
+
+   case Intrinsic::eh_dwarf_cfa: {
+     if (ExceptionHandling) {
+       MVT::ValueType VT = getValue(I.getOperand(1)).getValueType();
+       SDOperand Offset = DAG.getNode(ISD::ADD,
+                                      TLI.getPointerTy(),
+                                      DAG.getNode(ISD::FRAME_TO_ARGS_OFFSET,
+                                                  VT),
+                                      getValue(I.getOperand(1)));
+       setValue(&I, DAG.getNode(ISD::ADD,
+                                TLI.getPointerTy(),
+                                DAG.getNode(ISD::FRAMEADDR,
+                                            TLI.getPointerTy(),
+                                            DAG.getConstant(0,
+                                                            TLI.getPointerTy())),
+                                Offset));
+     } else {
+       setValue(&I, DAG.getConstant(0, TLI.getPointerTy()));
+     }
+
+     return 0;
+  }
+
   case Intrinsic::sqrt_f32:
   case Intrinsic::sqrt_f64:
     setValue(&I, DAG.getNode(ISD::FSQRT,
@@ -2578,10 +2816,6 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     SDOperand Arg = getValue(I.getOperand(1));
     MVT::ValueType Ty = Arg.getValueType();
     SDOperand result = DAG.getNode(ISD::CTTZ, Ty, Arg);
-    if (Ty < MVT::i32)
-      result = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, result);
-    else if (Ty > MVT::i32)
-      result = DAG.getNode(ISD::TRUNCATE, MVT::i32, result);
     setValue(&I, result);
     return 0;
   }
@@ -2589,10 +2823,6 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     SDOperand Arg = getValue(I.getOperand(1));
     MVT::ValueType Ty = Arg.getValueType();
     SDOperand result = DAG.getNode(ISD::CTLZ, Ty, Arg);
-    if (Ty < MVT::i32)
-      result = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, result);
-    else if (Ty > MVT::i32)
-      result = DAG.getNode(ISD::TRUNCATE, MVT::i32, result);
     setValue(&I, result);
     return 0;
   }
@@ -2600,10 +2830,6 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     SDOperand Arg = getValue(I.getOperand(1));
     MVT::ValueType Ty = Arg.getValueType();
     SDOperand result = DAG.getNode(ISD::CTPOP, Ty, Arg);
-    if (Ty < MVT::i32)
-      result = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, result);
-    else if (Ty > MVT::i32)
-      result = DAG.getNode(ISD::TRUNCATE, MVT::i32, result);
     setValue(&I, result);
     return 0;
   }
@@ -2627,6 +2853,28 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
   case Intrinsic::var_annotation:
     // Discard annotate attributes
     return 0;
+
+  case Intrinsic::adjust_trampoline: {
+    SDOperand Arg = getValue(I.getOperand(1));
+    setValue(&I, DAG.getNode(ISD::ADJUST_TRAMP, TLI.getPointerTy(), Arg));
+    return 0;
+  }
+
+  case Intrinsic::init_trampoline: {
+    const Function *F =
+      cast<Function>(IntrinsicInst::StripPointerCasts(I.getOperand(2)));
+
+    SDOperand Ops[6];
+    Ops[0] = getRoot();
+    Ops[1] = getValue(I.getOperand(1));
+    Ops[2] = getValue(I.getOperand(2));
+    Ops[3] = getValue(I.getOperand(3));
+    Ops[4] = DAG.getSrcValue(I.getOperand(1));
+    Ops[5] = DAG.getSrcValue(F);
+
+    DAG.setRoot(DAG.getNode(ISD::TRAMPOLINE, MVT::Other, Ops, 6));
+    return 0;
+  }
   }
 }
 
@@ -2656,6 +2904,8 @@ void SelectionDAGLowering::LowerCallTo(Instruction &I,
     Entry.isZExt  = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::ZExt);
     Entry.isInReg = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::InReg);
     Entry.isSRet  = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::StructRet);
+    Entry.isNest  = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::Nest);
+    Entry.isByVal = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::ByVal);
     Args.push_back(Entry);
   }
 
@@ -2755,198 +3005,12 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
 }
 
 
-/// getCopyFromParts - Create a value that contains the
-/// specified legal parts combined into the value they represent.
-static SDOperand getCopyFromParts(SelectionDAG &DAG,
-                                  const SDOperand *Parts,
-                                  unsigned NumParts,
-                                  MVT::ValueType PartVT,
-                                  MVT::ValueType ValueVT,
-                                  ISD::NodeType AssertOp = ISD::DELETED_NODE) {
-  if (!MVT::isVector(ValueVT) || NumParts == 1) {
-    SDOperand Val = Parts[0];
-
-    // If the value was expanded, copy from the top part.
-    if (NumParts > 1) {
-      assert(NumParts == 2 &&
-             "Cannot expand to more than 2 elts yet!");
-      SDOperand Hi = Parts[1];
-      return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Val, Hi);
-    }
-
-    // Otherwise, if the value was promoted or extended, truncate it to the
-    // appropriate type.
-    if (PartVT == ValueVT)
-      return Val;
-  
-    if (MVT::isVector(PartVT)) {
-      assert(MVT::isVector(ValueVT) && "Unknown vector conversion!");
-      return DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
-    }
-  
-    if (MVT::isInteger(PartVT) &&
-        MVT::isInteger(ValueVT)) {
-      if (ValueVT < PartVT) {
-        // For a truncate, see if we have any information to
-        // indicate whether the truncated bits will always be
-        // zero or sign-extension.
-        if (AssertOp != ISD::DELETED_NODE)
-          Val = DAG.getNode(AssertOp, PartVT, Val,
-                            DAG.getValueType(ValueVT));
-        return DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
-      } else {
-        return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
-      }
-    }
-  
-    if (MVT::isFloatingPoint(PartVT) &&
-        MVT::isFloatingPoint(ValueVT))
-      return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
-
-    if (MVT::getSizeInBits(PartVT) == 
-        MVT::getSizeInBits(ValueVT))
-      return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
-
-    assert(0 && "Unknown mismatch!");
-  }
-
-  // Handle a multi-element vector.
-  MVT::ValueType IntermediateVT, RegisterVT;
-  unsigned NumIntermediates;
-  unsigned NumRegs =
-    DAG.getTargetLoweringInfo()
-      .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
-                              RegisterVT);
-
-  assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
-  assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
-  assert(RegisterVT == Parts[0].getValueType() &&
-         "Part type doesn't match part!");
-
-  // Assemble the parts into intermediate operands.
-  SmallVector<SDOperand, 8> Ops(NumIntermediates);
-  if (NumIntermediates == NumParts) {
-    // If the register was not expanded, truncate or copy the value,
-    // as appropriate.
-    for (unsigned i = 0; i != NumParts; ++i)
-      Ops[i] = getCopyFromParts(DAG, &Parts[i], 1, PartVT, IntermediateVT);
-  } else if (NumParts > 0) {
-    // If the intermediate type was expanded, build the intermediate operands
-    // from the parts.
-    assert(NumIntermediates % NumParts == 0 &&
-           "Must expand into a divisible number of parts!");
-    unsigned Factor = NumIntermediates / NumParts;
-    for (unsigned i = 0; i != NumIntermediates; ++i)
-      Ops[i] = getCopyFromParts(DAG, &Parts[i * Factor], Factor,
-                                PartVT, IntermediateVT);
-  }
-  
-  // Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the intermediate
-  // operands.
-  return DAG.getNode(MVT::isVector(IntermediateVT) ?
-                       ISD::CONCAT_VECTORS :
-                       ISD::BUILD_VECTOR,
-                     ValueVT, &Ops[0], NumParts);
-}
-
-/// getCopyToParts - Create a series of nodes that contain the
-/// specified value split into legal parts.
-static void getCopyToParts(SelectionDAG &DAG,
-                           SDOperand Val,
-                           SDOperand *Parts,
-                           unsigned NumParts,
-                           MVT::ValueType PartVT) {
-  MVT::ValueType ValueVT = Val.getValueType();
-
-  if (!MVT::isVector(ValueVT) || NumParts == 1) {
-    // If the value was expanded, copy from the parts.
-    if (NumParts > 1) {
-      for (unsigned i = 0; i != NumParts; ++i)
-        Parts[i] = DAG.getNode(ISD::EXTRACT_ELEMENT, PartVT, Val,
-                               DAG.getConstant(i, MVT::i32));
-      return;
-    }
-
-    // If there is a single part and the types differ, this must be
-    // a promotion.
-    if (PartVT != ValueVT) {
-      if (MVT::isVector(PartVT)) {
-        assert(MVT::isVector(ValueVT) &&
-               "Not a vector-vector cast?");
-        Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
-      } else if (MVT::isInteger(PartVT) && MVT::isInteger(ValueVT)) {
-        if (PartVT < ValueVT)
-          Val = DAG.getNode(ISD::TRUNCATE, PartVT, Val);
-        else
-          Val = DAG.getNode(ISD::ANY_EXTEND, PartVT, Val);
-      } else if (MVT::isFloatingPoint(PartVT) &&
-                 MVT::isFloatingPoint(ValueVT)) {
-        Val = DAG.getNode(ISD::FP_EXTEND, PartVT, Val);
-      } else if (MVT::getSizeInBits(PartVT) == 
-                 MVT::getSizeInBits(ValueVT)) {
-        Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
-      } else {
-        assert(0 && "Unknown mismatch!");
-      }
-    }
-    Parts[0] = Val;
-    return;
-  }
-
-  // Handle a multi-element vector.
-  MVT::ValueType IntermediateVT, RegisterVT;
-  unsigned NumIntermediates;
-  unsigned NumRegs =
-    DAG.getTargetLoweringInfo()
-      .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
-                              RegisterVT);
-  unsigned NumElements = MVT::getVectorNumElements(ValueVT);
-
-  assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
-  assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
-
-  // Split the vector into intermediate operands.
-  SmallVector<SDOperand, 8> Ops(NumIntermediates);
-  for (unsigned i = 0; i != NumIntermediates; ++i)
-    if (MVT::isVector(IntermediateVT))
-      Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR,
-                           IntermediateVT, Val,
-                           DAG.getConstant(i * (NumElements / NumIntermediates),
-                                           MVT::i32));
-    else
-      Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
-                           IntermediateVT, Val, 
-                           DAG.getConstant(i, MVT::i32));
-
-  // Split the intermediate operands into legal parts.
-  if (NumParts == NumIntermediates) {
-    // If the register was not expanded, promote or copy the value,
-    // as appropriate.
-    for (unsigned i = 0; i != NumParts; ++i)
-      getCopyToParts(DAG, Ops[i], &Parts[i], 1, PartVT);
-  } else if (NumParts > 0) {
-    // If the intermediate type was expanded, split each the value into
-    // legal parts.
-    assert(NumParts % NumIntermediates == 0 &&
-           "Must expand into a divisible number of parts!");
-    unsigned Factor = NumParts / NumIntermediates;
-    for (unsigned i = 0; i != NumIntermediates; ++i)
-      getCopyToParts(DAG, Ops[i], &Parts[i * Factor], Factor, PartVT);
-  }
-}
-
-
 /// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from
 /// this value and returns the result as a ValueVT value.  This uses 
 /// Chain/Flag as the input and updates them for the output Chain/Flag.
 /// If the Flag pointer is NULL, no flag is used.
 SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
                                         SDOperand &Chain, SDOperand *Flag)const{
-  // Get the list of registers, in the appropriate order.
-  std::vector<unsigned> R(Regs);
-  if (!DAG.getTargetLoweringInfo().isLittleEndian())
-    std::reverse(R.begin(), R.end());
-
   // Copy the legal parts from the registers.
   unsigned NumParts = Regs.size();
   SmallVector<SDOperand, 8> Parts(NumParts);
@@ -2970,11 +3034,6 @@ SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
 /// If the Flag pointer is NULL, no flag is used.
 void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
                                  SDOperand &Chain, SDOperand *Flag) const {
-  // Get the list of registers, in the appropriate order.
-  std::vector<unsigned> R(Regs);
-  if (!DAG.getTargetLoweringInfo().isLittleEndian())
-    std::reverse(R.begin(), R.end());
-
   // Get the list of the values's legal parts.
   unsigned NumParts = Regs.size();
   SmallVector<SDOperand, 8> Parts(NumParts);
@@ -2983,8 +3042,8 @@ void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
   // Copy the parts into the registers.
   for (unsigned i = 0; i != NumParts; ++i) {
     SDOperand Part = Flag ?
-                     DAG.getCopyToReg(Chain, R[i], Parts[i], *Flag) :
-                     DAG.getCopyToReg(Chain, R[i], Parts[i]);
+                     DAG.getCopyToReg(Chain, Regs[i], Parts[i], *Flag) :
+                     DAG.getCopyToReg(Chain, Regs[i], Parts[i]);
     Chain = Part.getValue(0);
     if (Flag)
       *Flag = Part.getValue(1);
@@ -3780,6 +3839,17 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
       Flags |= ISD::ParamFlags::InReg;
     if (Attrs && Attrs->paramHasAttr(j, ParamAttr::StructRet))
       Flags |= ISD::ParamFlags::StructReturn;
+    if (Attrs && Attrs->paramHasAttr(j, ParamAttr::ByVal)) {
+      Flags |= ISD::ParamFlags::ByVal;
+      const PointerType *Ty = cast<PointerType>(I->getType());
+      const StructType *STy = cast<StructType>(Ty->getElementType());
+      unsigned StructAlign = Log2_32(getTargetData()->getABITypeAlignment(STy));
+      unsigned StructSize  = getTargetData()->getTypeSize(STy);
+      Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs);
+      Flags |= (StructSize  << ISD::ParamFlags::ByValSizeOffs);
+    }
+    if (Attrs && Attrs->paramHasAttr(j, ParamAttr::Nest))
+      Flags |= ISD::ParamFlags::Nest;
     Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs);
     
     switch (getTypeAction(VT)) {
@@ -3898,6 +3968,17 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
       Flags |= ISD::ParamFlags::InReg;
     if (Args[i].isSRet)
       Flags |= ISD::ParamFlags::StructReturn;
+    if (Args[i].isByVal) {
+      Flags |= ISD::ParamFlags::ByVal;
+      const PointerType *Ty = cast<PointerType>(Args[i].Ty);
+      const StructType *STy = cast<StructType>(Ty->getElementType());
+      unsigned StructAlign = Log2_32(getTargetData()->getABITypeAlignment(STy));
+      unsigned StructSize  = getTargetData()->getTypeSize(STy);
+      Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs);
+      Flags |= (StructSize  << ISD::ParamFlags::ByValSizeOffs);
+    }
+    if (Args[i].isNest)
+      Flags |= ISD::ParamFlags::Nest;
     Flags |= OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs;
     
     switch (getTypeAction(VT)) {
@@ -3957,7 +4038,7 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
   SDOperand Res = DAG.getNode(ISD::CALL,
                               DAG.getVTList(&RetTys[0], NumRegs + 1),
                               &Ops[0], Ops.size());
-  SDOperand Chain = Res.getValue(NumRegs);
+  Chain = Res.getValue(NumRegs);
 
   // Gather up the call result into a single value.
   if (RetTy != Type::VoidTy) {
@@ -4297,7 +4378,7 @@ static void copyCatchInfo(BasicBlock *SrcBB, BasicBlock *DestBB,
   assert(!FLI.MBBMap[SrcBB]->isLandingPad() &&
          "Copying catch info out of a landing pad!");
   for (BasicBlock::iterator I = SrcBB->begin(), E = --SrcBB->end(); I != E; ++I)
-    if (isFilterOrSelector(I)) {
+    if (isSelector(I)) {
       // Apply the catch info to DestBB.
       addCatchInfo(cast<CallInst>(*I), MMI, FLI.MBBMap[DestBB]);
 #ifndef NDEBUG
@@ -4341,19 +4422,19 @@ void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
     // function and list of typeids logically belong to the invoke (or, if you
     // like, the basic block containing the invoke), and need to be associated
     // with it in the dwarf exception handling tables.  Currently however the
-    // information is provided by intrinsics (eh.filter and eh.selector) that
-    // can be moved to unexpected places by the optimizers: if the unwind edge
-    // is critical, then breaking it can result in the intrinsics being in the
-    // successor of the landing pad, not the landing pad itself.  This results
-    // in exceptions not being caught because no typeids are associated with
-    // the invoke.  This may not be the only way things can go wrong, but it
-    // is the only way we try to work around for the moment.
+    // information is provided by an intrinsic (eh.selector) that can be moved
+    // to unexpected places by the optimizers: if the unwind edge is critical,
+    // then breaking it can result in the intrinsics being in the successor of
+    // the landing pad, not the landing pad itself.  This results in exceptions
+    // not being caught because no typeids are associated with the invoke.
+    // This may not be the only way things can go wrong, but it is the only way
+    // we try to work around for the moment.
     BranchInst *Br = dyn_cast<BranchInst>(LLVMBB->getTerminator());
 
     if (Br && Br->isUnconditional()) { // Critical edge?
       BasicBlock::iterator I, E;
       for (I = LLVMBB->begin(), E = --LLVMBB->end(); I != E; ++I)
-        if (isFilterOrSelector(I))
+        if (isSelector(I))
           break;
 
       if (I == E)
@@ -4394,8 +4475,8 @@ void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
   if (TI->getNumSuccessors())
     SuccsHandled.resize(BB->getParent()->getNumBlockIDs());
     
-  // Check successor nodes PHI nodes that expect a constant to be available from
-  // this block.
+  // Check successor nodes' PHI nodes that expect a constant to be available
+  // from this block.
   for (unsigned succ = 0, e = TI->getNumSuccessors(); succ != e; ++succ) {
     BasicBlock *SuccBB = TI->getSuccessor(succ);
     if (!isa<PHINode>(SuccBB->begin())) continue;
@@ -4752,7 +4833,7 @@ HazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() {
 /// actual value in the DAG on the RHS of an AND, and DesiredMaskS is the value
 /// specified in the .td file (e.g. 255).
 bool SelectionDAGISel::CheckAndMask(SDOperand LHS, ConstantSDNode *RHS, 
-                                    int64_t DesiredMaskS) {
+                                    int64_t DesiredMaskS) const {
   uint64_t ActualMask = RHS->getValue();
   uint64_t DesiredMask =DesiredMaskS & MVT::getIntVTBitMask(LHS.getValueType());
   
@@ -4781,7 +4862,7 @@ bool SelectionDAGISel::CheckAndMask(SDOperand LHS, ConstantSDNode *RHS,
 /// actual value in the DAG on the RHS of an OR, and DesiredMaskS is the value
 /// specified in the .td file (e.g. 255).
 bool SelectionDAGISel::CheckOrMask(SDOperand LHS, ConstantSDNode *RHS, 
-                                    int64_t DesiredMaskS) {
+                                    int64_t DesiredMaskS) const {
   uint64_t ActualMask = RHS->getValue();
   uint64_t DesiredMask =DesiredMaskS & MVT::getIntVTBitMask(LHS.getValueType());