diff options
| author | Chris Lattner <sabre@nondot.org> | 2006-02-22 00:56:39 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2006-02-22 00:56:39 +0000 | 
| commit | 7ad77dfc2add2ccfe65318a984ee17435bc02a3c (patch) | |
| tree | f2ea5616f40a850e8c81d941533672ae7eb751b4 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | |
| parent | cd78df1e85a9993b7c9f3a44888eead2195a5161 (diff) | |
| download | bcm5719-llvm-7ad77dfc2add2ccfe65318a984ee17435bc02a3c.tar.gz bcm5719-llvm-7ad77dfc2add2ccfe65318a984ee17435bc02a3c.zip | |
split register class handling from explicit physreg handling.
llvm-svn: 26308
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 111 | 
1 files changed, 77 insertions, 34 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;          } | 

