From bf996f1d5e441c7504ff155d818190f593d54672 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 30 Apr 2007 17:29:31 +0000 Subject: [PATCH] refactor GetRegistersForValue to take OpInfo as an argument instead of various pieces of it. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36592 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 199 +++++++++--------- 1 file changed, 101 insertions(+), 98 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 58a00bb7310..4f4c2cba00a 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -82,6 +82,8 @@ namespace { createDefaultScheduler); } // namespace +namespace { struct AsmOperandInfo; } + namespace { /// RegsForValue - This struct represents the physical registers that a /// particular value is assigned and the type information about the value. @@ -516,8 +518,7 @@ public: N = NewN; } - RegsForValue GetRegistersForValue(const std::string &ConstrCode, - MVT::ValueType VT, + RegsForValue GetRegistersForValue(AsmOperandInfo &OpInfo, bool OutReg, bool InReg, std::set &OutputRegs, std::set &InputRegs); @@ -3013,23 +3014,105 @@ isAllocatableRegister(unsigned Reg, MachineFunction &MF, return FoundRC; } + +namespace { +/// AsmOperandInfo - This contains information for each constraint that we are +/// lowering. +struct AsmOperandInfo : public InlineAsm::ConstraintInfo { + /// ConstraintCode - This contains the actual string for the code, like "m". + std::string ConstraintCode; + + /// ConstraintType - Information about the constraint code, e.g. Register, + /// RegisterClass, Memory, Other, Unknown. + TargetLowering::ConstraintType ConstraintType; + + /// CallOperand/CallOperandval - If this is the result output operand or a + /// clobber, this is null, otherwise it is the incoming operand to the + /// CallInst. This gets modified as the asm is processed. + SDOperand CallOperand; + Value *CallOperandVal; + + /// ConstraintVT - The ValueType for the operand value. + MVT::ValueType ConstraintVT; + + AsmOperandInfo(const InlineAsm::ConstraintInfo &info) + : InlineAsm::ConstraintInfo(info), + ConstraintType(TargetLowering::C_Unknown), + CallOperand(0,0), CallOperandVal(0), ConstraintVT(MVT::Other) { + } + + void ComputeConstraintToUse(const TargetLowering &TLI); +}; +} // end anon namespace. + +/// getConstraintGenerality - Return an integer indicating how general CT is. +static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) { + switch (CT) { + default: assert(0 && "Unknown constraint type!"); + case TargetLowering::C_Other: + case TargetLowering::C_Unknown: + return 0; + case TargetLowering::C_Register: + return 1; + case TargetLowering::C_RegisterClass: + return 2; + case TargetLowering::C_Memory: + return 3; + } +} + +void AsmOperandInfo::ComputeConstraintToUse(const TargetLowering &TLI) { + assert(!Codes.empty() && "Must have at least one constraint"); + + std::string *Current = &Codes[0]; + TargetLowering::ConstraintType CurType = TLI.getConstraintType(*Current); + if (Codes.size() == 1) { // Single-letter constraints ('r') are very common. + ConstraintCode = *Current; + ConstraintType = CurType; + return; + } + + unsigned CurGenerality = getConstraintGenerality(CurType); + + // If we have multiple constraints, try to pick the most general one ahead + // of time. This isn't a wonderful solution, but handles common cases. + for (unsigned j = 1, e = Codes.size(); j != e; ++j) { + TargetLowering::ConstraintType ThisType = TLI.getConstraintType(Codes[j]); + unsigned ThisGenerality = getConstraintGenerality(ThisType); + if (ThisGenerality > CurGenerality) { + // This constraint letter is more general than the previous one, + // use it. + CurType = ThisType; + Current = &Codes[j]; + CurGenerality = ThisGenerality; + } + } + + ConstraintCode = *Current; + ConstraintType = CurType; +} + + RegsForValue SelectionDAGLowering:: -GetRegistersForValue(const std::string &ConstrCode, - MVT::ValueType VT, bool isOutReg, bool isInReg, +GetRegistersForValue(AsmOperandInfo &OpInfo, bool isOutReg, bool isInReg, std::set &OutputRegs, std::set &InputRegs) { std::pair PhysReg = - TLI.getRegForInlineAsmConstraint(ConstrCode, VT); + TLI.getRegForInlineAsmConstraint(OpInfo.ConstraintCode,OpInfo.ConstraintVT); std::vector Regs; - unsigned NumRegs = VT != MVT::Other ? TLI.getNumElements(VT) : 1; + unsigned NumRegs = 1; + if (OpInfo.ConstraintVT != MVT::Other) + NumRegs = TLI.getNumElements(OpInfo.ConstraintVT); MVT::ValueType RegVT; - MVT::ValueType ValueVT = VT; + MVT::ValueType ValueVT = OpInfo.ConstraintVT; + MachineFunction &MF = DAG.getMachineFunction(); + // If this is a constraint for a specific physical register, like {r17}, // assign it now. if (PhysReg.first) { - if (VT == MVT::Other) + if (OpInfo.ConstraintVT == MVT::Other) ValueVT = *PhysReg.second->vt_begin(); // Get the actual register value type. This is important, because the user @@ -3067,11 +3150,11 @@ GetRegistersForValue(const std::string &ConstrCode, if (!isOutReg || !isInReg) { RegVT = *PhysReg.second->vt_begin(); - if (VT == MVT::Other) + if (OpInfo.ConstraintVT == MVT::Other) ValueVT = RegVT; // Create the appropriate number of virtual registers. - SSARegMap *RegMap = DAG.getMachineFunction().getSSARegMap(); + SSARegMap *RegMap = MF.getSSARegMap(); for (; NumRegs; --NumRegs) Regs.push_back(RegMap->createVirtualRegister(PhysReg.second)); @@ -3086,11 +3169,11 @@ GetRegistersForValue(const std::string &ConstrCode, // This is a reference to a register class that doesn't directly correspond // to an LLVM register class. Allocate NumRegs consecutive, available, // registers from the class. - RegClassRegs = TLI.getRegClassForInlineAsmConstraint(ConstrCode, VT); + RegClassRegs = TLI.getRegClassForInlineAsmConstraint(OpInfo.ConstraintCode, + OpInfo.ConstraintVT); } const MRegisterInfo *MRI = DAG.getTarget().getRegisterInfo(); - MachineFunction &MF = *CurMBB->getParent(); unsigned NumAllocated = 0; for (unsigned i = 0, e = RegClassRegs.size(); i != e; ++i) { unsigned Reg = RegClassRegs[i]; @@ -3126,7 +3209,7 @@ GetRegistersForValue(const std::string &ConstrCode, if (isInReg) InputRegs.insert(Reg); // Mark reg used. } - return RegsForValue(Regs, *RC->vt_begin(), VT); + return RegsForValue(Regs, *RC->vt_begin(), OpInfo.ConstraintVT); } } @@ -3134,83 +3217,6 @@ GetRegistersForValue(const std::string &ConstrCode, return RegsForValue(); } -namespace { -/// AsmOperandInfo - This contains information for each constraint that we are -/// lowering. -struct AsmOperandInfo : public InlineAsm::ConstraintInfo { - /// ConstraintCode - This contains the actual string for the code, like "m". - std::string ConstraintCode; - - /// ConstraintType - Information about the constraint code, e.g. Register, - /// RegisterClass, Memory, Other, Unknown. - TargetLowering::ConstraintType ConstraintType; - - /// CallOperand/CallOperandval - If this is the result output operand or a - /// clobber, this is null, otherwise it is the incoming operand to the - /// CallInst. This gets modified as the asm is processed. - SDOperand CallOperand; - Value *CallOperandVal; - - /// ConstraintVT - The ValueType for the operand value. - MVT::ValueType ConstraintVT; - - AsmOperandInfo(const InlineAsm::ConstraintInfo &info) - : InlineAsm::ConstraintInfo(info), - ConstraintType(TargetLowering::C_Unknown), - CallOperand(0,0), CallOperandVal(0), ConstraintVT(MVT::Other) { - } - - void ComputeConstraintToUse(const TargetLowering &TLI); -}; -} // end anon namespace. - -/// getConstraintGenerality - Return an integer indicating how general CT is. -static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) { - switch (CT) { - default: assert(0 && "Unknown constraint type!"); - case TargetLowering::C_Other: - case TargetLowering::C_Unknown: - return 0; - case TargetLowering::C_Register: - return 1; - case TargetLowering::C_RegisterClass: - return 2; - case TargetLowering::C_Memory: - return 3; - } -} - -void AsmOperandInfo::ComputeConstraintToUse(const TargetLowering &TLI) { - assert(!Codes.empty() && "Must have at least one constraint"); - - std::string *Current = &Codes[0]; - TargetLowering::ConstraintType CurType = TLI.getConstraintType(*Current); - if (Codes.size() == 1) { // Single-letter constraints ('r') are very common. - ConstraintCode = *Current; - ConstraintType = CurType; - return; - } - - unsigned CurGenerality = getConstraintGenerality(CurType); - - // If we have multiple constraints, try to pick the most general one ahead - // of time. This isn't a wonderful solution, but handles common cases. - for (unsigned j = 1, e = Codes.size(); j != e; ++j) { - TargetLowering::ConstraintType ThisType = TLI.getConstraintType(Codes[j]); - unsigned ThisGenerality = getConstraintGenerality(ThisType); - if (ThisGenerality > CurGenerality) { - // This constraint letter is more general than the previous one, - // use it. - CurType = ThisType; - Current = &Codes[j]; - CurGenerality = ThisGenerality; - } - } - - ConstraintCode = *Current; - ConstraintType = CurType; -} - /// visitInlineAsm - Handle a call to an InlineAsm object. /// @@ -3336,8 +3342,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { // Build a list of regs that this operand uses. This always has a single // element for promoted/expanded operands. - RegsForValue Regs = GetRegistersForValue(OpInfo.ConstraintCode, OpVT, - false, false, + RegsForValue Regs = GetRegistersForValue(OpInfo, false, false, OutputRegs, InputRegs); switch (OpInfo.Type) { @@ -3407,8 +3412,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { // Copy the output from the appropriate register. Find a register that // we can use. RegsForValue Regs = - GetRegistersForValue(OpInfo.ConstraintCode, OpInfo.ConstraintVT, - true, UsesInputRegister, + GetRegistersForValue(OpInfo, true, UsesInputRegister, OutputRegs, InputRegs); if (Regs.Regs.empty()) { cerr << "Couldn't allocate output reg for contraint '" @@ -3515,8 +3519,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { // Copy the input into the appropriate registers. RegsForValue InRegs = - GetRegistersForValue(OpInfo.ConstraintCode, OpInfo.ConstraintVT, - false, true, OutputRegs, InputRegs); + GetRegistersForValue(OpInfo, false, true, OutputRegs, InputRegs); // FIXME: should be match fail. assert(!InRegs.Regs.empty() && "Couldn't allocate input reg!"); @@ -3527,8 +3530,8 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { } case InlineAsm::isClobber: { RegsForValue ClobberedRegs = - GetRegistersForValue(OpInfo.ConstraintCode, MVT::Other, false, false, - OutputRegs, InputRegs); + GetRegistersForValue(OpInfo, false, + false, OutputRegs, InputRegs); // Add the clobbered value to the operand list, so that the register // allocator is aware that the physreg got clobbered. if (!ClobberedRegs.Regs.empty()) -- 2.34.1