diff options
-rw-r--r-- | include/llvm/MC/MCInstrDesc.h | 9 | ||||
-rw-r--r-- | include/llvm/Target/Target.td | 1 | ||||
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 7 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/InstrEmitter.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 10 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 23 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.h | 3 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 4 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 2 | ||||
-rw-r--r-- | utils/TableGen/CodeGenInstruction.cpp | 1 | ||||
-rw-r--r-- | utils/TableGen/CodeGenInstruction.h | 1 | ||||
-rw-r--r-- | utils/TableGen/InstrInfoEmitter.cpp | 1 |
12 files changed, 64 insertions, 2 deletions
diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index 5f5fa4c2f3..7061fcb012 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -116,6 +116,7 @@ namespace MCID { Commutable, ConvertibleTo3Addr, UsesCustomInserter, + HasPostISelHook, Rematerializable, CheapAsAMove, ExtraSrcRegAllocReq, @@ -476,6 +477,14 @@ public: return Flags & (1 << MCID::UsesCustomInserter); } + /// hasPostISelHook - Return true if this instruction requires *adjustment* + /// after instruction selection by calling a target hook. For example, this + /// can be used to fill in ARM 's' optional operand depending on whether + /// the conditional flag register is used. + bool hasPostISelHook() const { + return Flags & (1 << MCID::HasPostISelHook); + } + /// isRematerializable - Returns true if this instruction is a candidate for /// remat. This flag is deprecated, please don't use it anymore. If this /// flag is set, the isReallyTriviallyReMaterializable() method is called to diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 06c22996dc..b709b873f9 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -328,6 +328,7 @@ class Instruction { bit isPredicable = 0; // Is this instruction predicable? bit hasDelaySlot = 0; // Does this instruction have an delay slot? bit usesCustomInserter = 0; // Pseudo instr needing special help. + bit hasPostISelHook = 0; // To be *adjusted* after isel by target hook. bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains? bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction? bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction. diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index d960d76840..b5d739a2cb 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1471,6 +1471,13 @@ public: virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; + /// AdjustInstrPostInstrSelection - This method should be implemented by + /// targets that mark instructions with the 'hasPostISelHook' flag. These + /// instructions must be adjusted after instruction selection by target hooks. + /// e.g. To fill in optional defs for ARM 's' setting instructions. + virtual void + AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const; + //===--------------------------------------------------------------------===// // Addressing mode description hooks (used by LSR etc). // diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index 568f66c039..1e45ec6d11 100644 --- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -761,6 +761,10 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned, i != e; ++i) MI->addRegisterDead(IDList[i-II.getNumDefs()], TRI); } + + // Run post-isel target hook to adjust this instruction if needed. + if (II.hasPostISelHook()) + TLI->AdjustInstrPostInstrSelection(MI, Node); } /// EmitSpecialNode - Generate machine code for a target-independent node and diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index dda018b939..7a3ea86e8c 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -177,6 +177,16 @@ TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, return 0; } +void TargetLowering::AdjustInstrPostInstrSelection(MachineInstr *MI, + SDNode *Node) const { +#ifndef NDEBUG + dbgs() << "If a target marks an instruction with " + "'hasPostISelHook', it must implement " + "TargetLowering::AdjustInstrPostInstrSelection!"; +#endif + llvm_unreachable(0); +} + //===----------------------------------------------------------------------===// // SelectionDAGISel code //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 29fb268ef4..52684663af 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -5474,6 +5474,29 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, } } +void ARMTargetLowering::AdjustInstrPostInstrSelection(MachineInstr *MI, + SDNode *Node) const { + // Adjust potentially 's' setting instructions after isel, i.e. ADC, SBC, + // RSB, RSC. Coming out of isel, they have an implicit CPSR def, but the + // optional operand is not filled in. If the carry bit is used, then change + // the optional operand to CPSR. Otherwise, remove the CPSR implicit def. + const MCInstrDesc &MCID = MI->getDesc(); + if (Node->hasAnyUseOfValue(1)) { + MachineOperand &MO = MI->getOperand(MCID.getNumOperands() - 2); + MO.setReg(ARM::CPSR); + MO.setIsDef(true); + } else { + for (unsigned i = MCID.getNumOperands(), e = MI->getNumOperands(); + i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) { + MI->RemoveOperand(i); + break; + } + } + } +} + //===----------------------------------------------------------------------===// // ARM Optimization Hooks //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index 4a07ebf97b..92164aef00 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -249,6 +249,9 @@ namespace llvm { EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; + virtual void + AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const; + SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const; virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index f4d13577de..08b0954efa 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1290,7 +1290,7 @@ class AI_exta_rrot_np<bits<8> opcod, string opc> /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube. multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, string baseOpc, bit Commutable = 0> { - let Defs = [CPSR], Uses = [CPSR] in { + let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in { def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm", [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_imm:$imm, CPSR))]>, @@ -1378,7 +1378,7 @@ multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, /// AI1_rsc_irs - Define instructions and patterns for rsc multiclass AI1_rsc_irs<bits<4> opcod, string opc, PatFrag opnode, string baseOpc> { - let Defs = [CPSR], Uses = [CPSR] in { + let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in { def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm", [(set GPR:$Rd, CPSR, (opnode so_imm:$imm, GPR:$Rn, CPSR))]>, diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 34a9147233..a7652f670a 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -1661,10 +1661,12 @@ defm t2SUBS : T2I_bin_s_irs <0b1101, "sub", IIC_iALUi, IIC_iALUr, IIC_iALUsi, BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>; +let hasPostISelHook = 1 in { defm t2ADC : T2I_adde_sube_irs<0b1010, "adc", BinOpWithFlagFrag<(ARMadde node:$LHS, node:$RHS, node:$FLAG)>, 1>; defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc", BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>>; +} // RSB defm t2RSB : T2I_rbin_irs <0b1110, "rsb", diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index b4f9d15071..4b252774f0 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -309,6 +309,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R), Operands(R) { isReMaterializable = R->getValueAsBit("isReMaterializable"); hasDelaySlot = R->getValueAsBit("hasDelaySlot"); usesCustomInserter = R->getValueAsBit("usesCustomInserter"); + hasPostISelHook = R->getValueAsBit("hasPostISelHook"); hasCtrlDep = R->getValueAsBit("hasCtrlDep"); isNotDuplicable = R->getValueAsBit("isNotDuplicable"); hasSideEffects = R->getValueAsBit("hasSideEffects"); diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index 8d7669aca9..468277aa96 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -233,6 +233,7 @@ namespace llvm { bool isReMaterializable; bool hasDelaySlot; bool usesCustomInserter; + bool hasPostISelHook; bool hasCtrlDep; bool isNotDuplicable; bool hasSideEffects; diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 5ebaf17465..1cf7c90496 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -288,6 +288,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, if (Inst.isNotDuplicable) OS << "|(1<<MCID::NotDuplicable)"; if (Inst.Operands.hasOptionalDef) OS << "|(1<<MCID::HasOptionalDef)"; if (Inst.usesCustomInserter) OS << "|(1<<MCID::UsesCustomInserter)"; + if (Inst.hasPostISelHook) OS << "|(1<<MCID::HasPostISelHook)"; if (Inst.Operands.isVariadic)OS << "|(1<<MCID::Variadic)"; if (Inst.hasSideEffects) OS << "|(1<<MCID::UnmodeledSideEffects)"; if (Inst.isAsCheapAsAMove) OS << "|(1<<MCID::CheapAsAMove)"; |