diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 111 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.h | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/TargetLowering.cpp | 32 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.h | 4 | 
6 files changed, 108 insertions, 57 deletions
| diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index c8e94019e32..d16b070c51f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1187,6 +1187,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {    bool hasSideEffects = IA->hasSideEffects();    std::vector<InlineAsm::ConstraintInfo> Constraints = IA->ParseConstraints(); +  std::vector<MVT::ValueType> ConstraintVTs;    /// AsmNodeOperands - A list of pairs.  The first element is a register, the    /// second is a bitfield where bit #0 is set if it is a use and bit #1 is set @@ -1203,14 +1204,43 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {    // could let the LLVM RA do its thing, but we currently don't.  Do a prepass    // over the constraints, collecting fixed registers that we know we can't use.    std::set<unsigned> OutputRegs, InputRegs; +  unsigned OpNum = 1;    for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {      assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!");      std::string &ConstraintCode = Constraints[i].Codes[0]; -    std::vector<unsigned> Regs = -      TLI.getRegForInlineAsmConstraint(ConstraintCode, MVT::Other); -    if (Regs.size() != 1) continue;  // Not assigned a fixed reg. -    unsigned TheReg = Regs[0]; +    MVT::ValueType OpVT; + +    // Compute the value type for each operand and add it to ConstraintVTs. +    switch (Constraints[i].Type) { +    case InlineAsm::isOutput: +      if (!Constraints[i].isIndirectOutput) { +        assert(I.getType() != Type::VoidTy && "Bad inline asm!"); +        OpVT = TLI.getValueType(I.getType()); +      } else { +        Value *CallOperand = I.getOperand(OpNum); +        const Type *OpTy = CallOperand->getType(); +        OpVT = TLI.getValueType(cast<PointerType>(OpTy)->getElementType()); +        OpNum++;  // Consumes a call operand. +      } +      break; +    case InlineAsm::isInput: +      OpVT = TLI.getValueType(I.getOperand(OpNum)->getType()); +      OpNum++;  // Consumes a call operand. +      break; +    case InlineAsm::isClobber: +      OpVT = MVT::Other; +      break; +    } +     +    ConstraintVTs.push_back(OpVT); + +    std::pair<unsigned, const TargetRegisterClass*> Reg =  +       TLI.getRegForInlineAsmConstraint(ConstraintCode, OpVT); +    if (Reg.first == 0) continue;  // Not assigned a fixed reg. +    unsigned TheReg = Reg.first; +     +    // FIXME: Handle expanded physreg refs!      switch (Constraints[i].Type) {      case InlineAsm::isOutput: @@ -1221,15 +1251,15 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {        if (Constraints[i].isEarlyClobber || Constraints[i].hasMatchingInput)          InputRegs.insert(TheReg);        break; +    case InlineAsm::isInput: +      // We can't assign any other input to this register. +      InputRegs.insert(TheReg); +      break;      case InlineAsm::isClobber:        // Clobbered regs cannot be used as inputs or outputs.        InputRegs.insert(TheReg);        OutputRegs.insert(TheReg);        break; -    case InlineAsm::isInput: -      // We can't assign any other input to this register. -      InputRegs.insert(TheReg); -      break;      }    }       @@ -1238,28 +1268,32 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {    unsigned RetValReg = 0;    std::vector<std::pair<unsigned, Value*> > IndirectStoresToEmit;    bool FoundOutputConstraint = false; -  unsigned OpNum = 1; +  OpNum = 1;    for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {      assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!");      std::string &ConstraintCode = Constraints[i].Codes[0]; -    Value *CallOperand = I.getOperand(OpNum); -    MVT::ValueType CallOpVT = TLI.getValueType(CallOperand->getType()); +      switch (Constraints[i].Type) {      case InlineAsm::isOutput: { -      // Copy the output from the appropriate register. -      std::vector<unsigned> Regs = -        TLI.getRegForInlineAsmConstraint(ConstraintCode, CallOpVT); - -      // Find a regsister that we can use. +      // Copy the output from the appropriate register.  Find a regsister that +      // we can use. +       +      // Check to see if this is a physreg reference. +      std::pair<unsigned, const TargetRegisterClass*> PhysReg =  +         TLI.getRegForInlineAsmConstraint(ConstraintCode, ConstraintVTs[i]);        unsigned DestReg; -      if (Regs.size() == 1) -        DestReg = Regs[0]; +      if (PhysReg.first) +        DestReg = PhysReg.first;        else { -        bool UsesInputRegister = false; +        std::vector<unsigned> Regs = +          TLI.getRegClassForInlineAsmConstraint(ConstraintCode,  +                                                ConstraintVTs[i]); +          // If this is an early-clobber output, or if there is an input          // constraint that matches this, we need to reserve the input register          // so no other inputs allocate to it. +        bool UsesInputRegister = false;          if (Constraints[i].isEarlyClobber || Constraints[i].hasMatchingInput)            UsesInputRegister = true;          DestReg = GetAvailableRegister(true, UsesInputRegister,  @@ -1276,24 +1310,21 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {          assert(I.getType() != Type::VoidTy && "Bad inline asm!");          RetValReg = DestReg; -        OpTy = I.getType();        } else { +        Value *CallOperand = I.getOperand(OpNum);          IndirectStoresToEmit.push_back(std::make_pair(DestReg, CallOperand)); -        OpTy = CallOperand->getType(); -        OpTy = cast<PointerType>(OpTy)->getElementType();          OpNum++;  // Consumes a call operand.        }        // Add information to the INLINEASM node to know that this register is        // set. -      AsmNodeOperands.push_back(DAG.getRegister(DestReg, -                                                TLI.getValueType(OpTy))); +      AsmNodeOperands.push_back(DAG.getRegister(DestReg, ConstraintVTs[i]));        AsmNodeOperands.push_back(DAG.getConstant(2, MVT::i32)); // ISDEF        break;      }      case InlineAsm::isInput: { -      const Type *OpTy = CallOperand->getType(); +      Value *CallOperand = I.getOperand(OpNum);        OpNum++;  // Consumes a call operand.        unsigned SrcReg; @@ -1306,33 +1337,45 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {          // just use its register.          unsigned OperandNo = atoi(ConstraintCode.c_str());          SrcReg = cast<RegisterSDNode>(AsmNodeOperands[OperandNo*2+2])->getReg(); -        ResOp = DAG.getRegister(SrcReg, CallOpVT); +        ResOp = DAG.getRegister(SrcReg, ConstraintVTs[i]);          ResOpType = 1;          Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag);          Flag = Chain.getValue(1);        } else { -        TargetLowering::ConstraintType CTy = TargetLowering::C_RegisterClass; +        TargetLowering::ConstraintType CTy = TargetLowering::C_Register;          if (ConstraintCode.size() == 1)   // not a physreg name.            CTy = TLI.getConstraintType(ConstraintCode[0]);          switch (CTy) {          default: assert(0 && "Unknown constraint type! FAIL!"); +        case TargetLowering::C_Register: { +          std::pair<unsigned, const TargetRegisterClass*> PhysReg =  +            TLI.getRegForInlineAsmConstraint(ConstraintCode, ConstraintVTs[i]); +          // FIXME: should be match fail. +          assert(PhysReg.first && "Unknown physical register name!"); +          SrcReg = PhysReg.first; + +          Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag); +          Flag = Chain.getValue(1); +           +          ResOp = DAG.getRegister(SrcReg, ConstraintVTs[i]); +          ResOpType = 1; +          break; +        }          case TargetLowering::C_RegisterClass: {            // Copy the input into the appropriate register.            std::vector<unsigned> Regs = -            TLI.getRegForInlineAsmConstraint(ConstraintCode, CallOpVT); -          if (Regs.size() == 1) -            SrcReg = Regs[0]; -          else -            SrcReg = GetAvailableRegister(false, true, Regs,  -                                          OutputRegs, InputRegs); +            TLI.getRegClassForInlineAsmConstraint(ConstraintCode,  +                                                  ConstraintVTs[i]); +          SrcReg = GetAvailableRegister(false, true, Regs,  +                                        OutputRegs, InputRegs);            // FIXME: should be match fail.            assert(SrcReg && "Wasn't able to allocate register!");            Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag);            Flag = Chain.getValue(1); -          ResOp = DAG.getRegister(SrcReg, CallOpVT); +          ResOp = DAG.getRegister(SrcReg, ConstraintVTs[i]);            ResOpType = 1;            break;          } diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 243c51d7c9d..003d16c26b1 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -999,8 +999,8 @@ PPCTargetLowering::getConstraintType(char ConstraintLetter) const {  std::vector<unsigned> PPCTargetLowering:: -getRegForInlineAsmConstraint(const std::string &Constraint, -                             MVT::ValueType VT) const { +getRegClassForInlineAsmConstraint(const std::string &Constraint, +                                  MVT::ValueType VT) const {    if (Constraint.size() == 1) {      switch (Constraint[0]) {      // GCC RS6000 Constraint Letters      default: break;  // Unknown constriant letter @@ -1051,8 +1051,7 @@ getRegForInlineAsmConstraint(const std::string &Constraint,      }    } -  // Handle explicit register names. -  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); +  return std::vector<unsigned>();  }  // isOperandValidForConstraint diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h index a1ce5545c32..86264aec38b 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.h +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h @@ -99,8 +99,8 @@ namespace llvm {      ConstraintType getConstraintType(char ConstraintLetter) const;      std::vector<unsigned>  -      getRegForInlineAsmConstraint(const std::string &Constraint, -                                   MVT::ValueType VT) const; +      getRegClassForInlineAsmConstraint(const std::string &Constraint, +                                        MVT::ValueType VT) const;      bool isOperandValidForConstraint(SDOperand Op, char ConstraintLetter);    };  } diff --git a/llvm/lib/Target/TargetLowering.cpp b/llvm/lib/Target/TargetLowering.cpp index 79211debc99..e82e7f768ea 100644 --- a/llvm/lib/Target/TargetLowering.cpp +++ b/llvm/lib/Target/TargetLowering.cpp @@ -745,24 +745,34 @@ bool TargetLowering::isOperandValidForConstraint(SDOperand Op,  std::vector<unsigned> TargetLowering:: +getRegClassForInlineAsmConstraint(const std::string &Constraint, +                                  MVT::ValueType VT) const { +  return std::vector<unsigned>(); +} + + +std::pair<unsigned, const TargetRegisterClass*> TargetLowering::  getRegForInlineAsmConstraint(const std::string &Constraint,                               MVT::ValueType VT) const { -  // Not a physreg, must not be a register reference or something. -  if (Constraint[0] != '{') return std::vector<unsigned>(); +  if (Constraint[0] != '{') +    return std::pair<unsigned, const TargetRegisterClass*>(0, 0);    assert(*(Constraint.end()-1) == '}' && "Not a brace enclosed constraint?");    // Remove the braces from around the name.    std::string RegName(Constraint.begin()+1, Constraint.end()-1); -   -  // Scan to see if this constraint is a register name. + +  // Figure out which register class contains this reg.    const MRegisterInfo *RI = TM.getRegisterInfo(); -  for (unsigned i = 1, e = RI->getNumRegs(); i != e; ++i) { -    if (const char *Name = RI->get(i).Name) -      if (StringsEqualNoCase(RegName, Name)) -        return std::vector<unsigned>(1, i); +  for (MRegisterInfo::regclass_iterator RCI = RI->regclass_begin(), +       E = RI->regclass_end(); RCI != E; ++RCI) { +    const TargetRegisterClass *RC = *RCI; +    for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end();  +         I != E; ++I) { +      if (StringsEqualNoCase(RegName, RI->get(*I).Name)) { +        return std::make_pair(*I, RC); +      } +    }    } -  // Unknown physreg. -  return std::vector<unsigned>(); +  return std::pair<unsigned, const TargetRegisterClass*>(0, 0);  } - diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index bbf590b8ac3..e32cc0f2bd8 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -1961,8 +1961,8 @@ void X86TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,  }  std::vector<unsigned> X86TargetLowering:: -getRegForInlineAsmConstraint(const std::string &Constraint, -                             MVT::ValueType VT) const { +getRegClassForInlineAsmConstraint(const std::string &Constraint, +                                  MVT::ValueType VT) const {    if (Constraint.size() == 1) {      // FIXME: not handling fp-stack yet!      // FIXME: not handling MMX registers yet ('y' constraint). @@ -1993,6 +1993,5 @@ getRegForInlineAsmConstraint(const std::string &Constraint,      }    } -  // Handle explicit register names. -  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); +  return std::vector<unsigned>();  } diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index 375320c7714..d45afa4a184 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -224,8 +224,8 @@ namespace llvm {      SDOperand getReturnAddressFrameIndex(SelectionDAG &DAG);      std::vector<unsigned>  -      getRegForInlineAsmConstraint(const std::string &Constraint, -                                   MVT::ValueType VT) const; +      getRegClassForInlineAsmConstraint(const std::string &Constraint, +                                        MVT::ValueType VT) const;    private:      // C Calling Convention implementation.      std::vector<SDOperand> LowerCCCArguments(Function &F, SelectionDAG &DAG); | 

