forked from OSchip/llvm-project
This adds a new field isAdd to MCInstrDesc. The ARM and Hexagon instruction
descriptions now tag add instructions, and the Hexagon backend is using this to identify loop induction statements. Patch by Sam Parker and Sjoerd Meijer. Differential Revision: https://reviews.llvm.org/D23601 llvm-svn: 281304
This commit is contained in:
parent
b79f4d3970
commit
05453991fe
|
@ -124,6 +124,7 @@ enum Flag {
|
|||
Pseudo,
|
||||
Return,
|
||||
Call,
|
||||
Add,
|
||||
Barrier,
|
||||
Terminator,
|
||||
Branch,
|
||||
|
@ -234,6 +235,9 @@ public:
|
|||
/// \brief Return true if the instruction is a return.
|
||||
bool isReturn() const { return Flags & (1ULL << MCID::Return); }
|
||||
|
||||
/// \brief Return true if the instruction is an add instruction.
|
||||
bool isAdd() const { return Flags & (1ULL << MCID::Add); }
|
||||
|
||||
/// \brief Return true if the instruction is a call.
|
||||
bool isCall() const { return Flags & (1ULL << MCID::Call); }
|
||||
|
||||
|
|
|
@ -371,6 +371,7 @@ class Instruction {
|
|||
bit isSelect = 0; // Is this instruction a select instruction?
|
||||
bit isBarrier = 0; // Can control flow fall through this instruction?
|
||||
bit isCall = 0; // Is this instruction a call instruction?
|
||||
bit isAdd = 0; // Is this instruction an add instruction?
|
||||
bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand?
|
||||
bit mayLoad = ?; // Is it possible for this inst to read memory?
|
||||
bit mayStore = ?; // Is it possible for this inst to write memory?
|
||||
|
|
|
@ -3498,6 +3498,7 @@ def UBFX : I<(outs GPRnopc:$Rd),
|
|||
// Arithmetic Instructions.
|
||||
//
|
||||
|
||||
let isAdd = 1 in
|
||||
defm ADD : AsI1_bin_irs<0b0100, "add",
|
||||
IIC_iALUi, IIC_iALUr, IIC_iALUsr, add, 1>;
|
||||
defm SUB : AsI1_bin_irs<0b0010, "sub",
|
||||
|
@ -3513,9 +3514,11 @@ defm SUB : AsI1_bin_irs<0b0010, "sub",
|
|||
// FIXME: Eliminate ADDS/SUBS pseudo opcodes after adding tablegen
|
||||
// support for an optional CPSR definition that corresponds to the DAG
|
||||
// node's second value. We can then eliminate the implicit def of CPSR.
|
||||
let isAdd = 1 in
|
||||
defm ADDS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, ARMaddc, 1>;
|
||||
defm SUBS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, ARMsubc>;
|
||||
|
||||
let isAdd = 1 in
|
||||
defm ADC : AI1_adde_sube_irs<0b0101, "adc", ARMadde, 1>;
|
||||
defm SBC : AI1_adde_sube_irs<0b0110, "sbc", ARMsube>;
|
||||
|
||||
|
|
|
@ -904,49 +904,51 @@ class T1sItGenEncodeImm<bits<5> opA, dag oops, dag iops, InstrItinClass itin,
|
|||
let Inst{7-0} = imm8;
|
||||
}
|
||||
|
||||
// Add with carry register
|
||||
let isCommutable = 1, Uses = [CPSR] in
|
||||
def tADC : // A8.6.2
|
||||
T1sItDPEncode<0b0101, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), IIC_iALUr,
|
||||
"adc", "\t$Rdn, $Rm",
|
||||
[(set tGPR:$Rdn, (adde tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
|
||||
let isAdd = 1 in {
|
||||
// Add with carry register
|
||||
let isCommutable = 1, Uses = [CPSR] in
|
||||
def tADC : // A8.6.2
|
||||
T1sItDPEncode<0b0101, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), IIC_iALUr,
|
||||
"adc", "\t$Rdn, $Rm",
|
||||
[(set tGPR:$Rdn, (adde tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
|
||||
|
||||
// Add immediate
|
||||
def tADDi3 : // A8.6.4 T1
|
||||
T1sIGenEncodeImm<0b01110, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
|
||||
IIC_iALUi,
|
||||
"add", "\t$Rd, $Rm, $imm3",
|
||||
[(set tGPR:$Rd, (add tGPR:$Rm, imm0_7:$imm3))]>,
|
||||
Sched<[WriteALU]> {
|
||||
bits<3> imm3;
|
||||
let Inst{8-6} = imm3;
|
||||
}
|
||||
// Add immediate
|
||||
def tADDi3 : // A8.6.4 T1
|
||||
T1sIGenEncodeImm<0b01110, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
|
||||
IIC_iALUi,
|
||||
"add", "\t$Rd, $Rm, $imm3",
|
||||
[(set tGPR:$Rd, (add tGPR:$Rm, imm0_7:$imm3))]>,
|
||||
Sched<[WriteALU]> {
|
||||
bits<3> imm3;
|
||||
let Inst{8-6} = imm3;
|
||||
}
|
||||
|
||||
def tADDi8 : // A8.6.4 T2
|
||||
T1sItGenEncodeImm<{1,1,0,?,?}, (outs tGPR:$Rdn),
|
||||
(ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi,
|
||||
"add", "\t$Rdn, $imm8",
|
||||
[(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255:$imm8))]>,
|
||||
Sched<[WriteALU]>;
|
||||
def tADDi8 : // A8.6.4 T2
|
||||
T1sItGenEncodeImm<{1,1,0,?,?}, (outs tGPR:$Rdn),
|
||||
(ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi,
|
||||
"add", "\t$Rdn, $imm8",
|
||||
[(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255:$imm8))]>,
|
||||
Sched<[WriteALU]>;
|
||||
|
||||
// Add register
|
||||
let isCommutable = 1 in
|
||||
def tADDrr : // A8.6.6 T1
|
||||
T1sIGenEncode<0b01100, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
|
||||
IIC_iALUr,
|
||||
"add", "\t$Rd, $Rn, $Rm",
|
||||
[(set tGPR:$Rd, (add tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
|
||||
// Add register
|
||||
let isCommutable = 1 in
|
||||
def tADDrr : // A8.6.6 T1
|
||||
T1sIGenEncode<0b01100, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
|
||||
IIC_iALUr,
|
||||
"add", "\t$Rd, $Rn, $Rm",
|
||||
[(set tGPR:$Rd, (add tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
|
||||
|
||||
let hasSideEffects = 0 in
|
||||
def tADDhirr : T1pIt<(outs GPR:$Rdn), (ins GPR:$Rn, GPR:$Rm), IIC_iALUr,
|
||||
"add", "\t$Rdn, $Rm", []>,
|
||||
T1Special<{0,0,?,?}>, Sched<[WriteALU]> {
|
||||
// A8.6.6 T2
|
||||
bits<4> Rdn;
|
||||
bits<4> Rm;
|
||||
let Inst{7} = Rdn{3};
|
||||
let Inst{6-3} = Rm;
|
||||
let Inst{2-0} = Rdn{2-0};
|
||||
let hasSideEffects = 0 in
|
||||
def tADDhirr : T1pIt<(outs GPR:$Rdn), (ins GPR:$Rn, GPR:$Rm), IIC_iALUr,
|
||||
"add", "\t$Rdn, $Rm", []>,
|
||||
T1Special<{0,0,?,?}>, Sched<[WriteALU]> {
|
||||
// A8.6.6 T2
|
||||
bits<4> Rdn;
|
||||
bits<4> Rm;
|
||||
let Inst{7} = Rdn{3};
|
||||
let Inst{6-3} = Rm;
|
||||
let Inst{2-0} = Rdn{2-0};
|
||||
}
|
||||
}
|
||||
|
||||
// AND register
|
||||
|
|
|
@ -2038,6 +2038,7 @@ def : Thumb2ExtractPat<(add rGPR:$Rn, (and (srl rGPR:$Rm, imm8_or_16:$rot),
|
|||
// Arithmetic Instructions.
|
||||
//
|
||||
|
||||
let isAdd = 1 in
|
||||
defm t2ADD : T2I_bin_ii12rs<0b000, "add", add, 1>;
|
||||
defm t2SUB : T2I_bin_ii12rs<0b101, "sub", sub>;
|
||||
|
||||
|
|
|
@ -411,10 +411,8 @@ bool HexagonHardwareLoops::findInductionRegister(MachineLoop *L,
|
|||
|
||||
unsigned PhiOpReg = Phi->getOperand(i).getReg();
|
||||
MachineInstr *DI = MRI->getVRegDef(PhiOpReg);
|
||||
unsigned UpdOpc = DI->getOpcode();
|
||||
bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp);
|
||||
|
||||
if (isAdd) {
|
||||
if (DI->getDesc().isAdd()) {
|
||||
// If the register operand to the add is the PHI we're looking at, this
|
||||
// meets the induction pattern.
|
||||
unsigned IndReg = DI->getOperand(1).getReg();
|
||||
|
@ -1592,10 +1590,8 @@ bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) {
|
|||
|
||||
unsigned PhiReg = Phi->getOperand(i).getReg();
|
||||
MachineInstr *DI = MRI->getVRegDef(PhiReg);
|
||||
unsigned UpdOpc = DI->getOpcode();
|
||||
bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp);
|
||||
|
||||
if (isAdd) {
|
||||
if (DI->getDesc().isAdd()) {
|
||||
// If the register operand to the add/sub is the PHI we are looking
|
||||
// at, this meets the induction pattern.
|
||||
unsigned IndReg = DI->getOperand(1).getReg();
|
||||
|
|
|
@ -406,7 +406,7 @@ multiclass Addri_Pred<string mnemonic, bit PredNot> {
|
|||
let isExtendable = 1, isExtentSigned = 1, InputType = "imm" in
|
||||
multiclass Addri_base<string mnemonic, SDNode OpNode> {
|
||||
let CextOpcode = mnemonic, BaseOpcode = mnemonic#_ri in {
|
||||
let opExtendable = 2, opExtentBits = 16, isPredicable = 1 in
|
||||
let opExtendable = 2, opExtentBits = 16, isPredicable = 1, isAdd = 1 in
|
||||
def A2_#NAME : T_Addri<s16Ext>;
|
||||
|
||||
let opExtendable = 3, opExtentBits = 8, isPredicated = 1 in {
|
||||
|
@ -1292,6 +1292,7 @@ class T_ALU64_arith<string mnemonic, bits<3> MajOp, bits<3> MinOp, bit IsSat,
|
|||
: T_ALU64_rr<mnemonic, !if(IsSat,":sat",""), 0b0011, MajOp, MinOp, OpsRev,
|
||||
IsComm, "">;
|
||||
|
||||
let isAdd = 1 in
|
||||
def A2_addp : T_ALU64_arith<"add", 0b000, 0b111, 0, 0, 1>;
|
||||
def A2_subp : T_ALU64_arith<"sub", 0b001, 0b111, 0, 1, 0>;
|
||||
|
||||
|
|
|
@ -4,37 +4,17 @@
|
|||
target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-v64:64:64-v32:32:32-a0:0-n16:32"
|
||||
target triple = "hexagon-unknown-none"
|
||||
|
||||
%struct.aDataType = type { i16, i16, i16, i16, i16, i16*, i16*, i16*, i8*, i16*, i16*, i16*, i8* }
|
||||
|
||||
define i8* @a_get_score(%struct.aDataType* nocapture %pData, i16 signext %gmmModelIndex, i16* nocapture %pGmmScoreL16Q4) #0 {
|
||||
entry:
|
||||
%numSubVector = getelementptr inbounds %struct.aDataType, %struct.aDataType* %pData, i32 0, i32 3
|
||||
%0 = load i16, i16* %numSubVector, align 2, !tbaa !0
|
||||
%and = and i16 %0, -4
|
||||
%b = getelementptr inbounds %struct.aDataType, %struct.aDataType* %pData, i32 0, i32 8
|
||||
%1 = load i8*, i8** %b, align 4, !tbaa !3
|
||||
define i32 @foo(i16 %a, i32 %b) #0 {
|
||||
%and = and i16 %a, -4
|
||||
%conv3 = sext i16 %and to i32
|
||||
%cmp21 = icmp sgt i16 %and, 0
|
||||
br i1 %cmp21, label %for.inc.preheader, label %for.end
|
||||
|
||||
for.inc.preheader: ; preds = %entry
|
||||
br label %for.inc
|
||||
|
||||
for.inc: ; preds = %for.inc.preheader, %for.inc
|
||||
%j.022 = phi i32 [ %phitmp, %for.inc ], [ 0, %for.inc.preheader ]
|
||||
%add13 = mul i32 %j.022, 65536
|
||||
%add13 = mul i32 %b, 65536
|
||||
%sext = add i32 %add13, 262144
|
||||
%phitmp = ashr exact i32 %sext, 16
|
||||
%cmp = icmp slt i32 %phitmp, %conv3
|
||||
br i1 %cmp, label %for.inc, label %for.end.loopexit
|
||||
|
||||
for.end.loopexit: ; preds = %for.inc
|
||||
br label %for.end
|
||||
|
||||
for.end: ; preds = %for.end.loopexit, %entry
|
||||
ret i8* %1
|
||||
ret i32 %phitmp
|
||||
}
|
||||
|
||||
|
||||
attributes #0 = { nounwind readonly "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
|
||||
!0 = !{!"short", !1}
|
||||
|
|
|
@ -230,6 +230,7 @@ template <typename T> class ArrayRef;
|
|||
bool isSelect : 1;
|
||||
bool isBarrier : 1;
|
||||
bool isCall : 1;
|
||||
bool isAdd : 1;
|
||||
bool canFoldAsLoad : 1;
|
||||
bool mayLoad : 1;
|
||||
bool mayLoad_Unset : 1;
|
||||
|
|
|
@ -482,6 +482,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
|||
if (Inst.isCompare) OS << "|(1ULL<<MCID::Compare)";
|
||||
if (Inst.isMoveImm) OS << "|(1ULL<<MCID::MoveImm)";
|
||||
if (Inst.isBitcast) OS << "|(1ULL<<MCID::Bitcast)";
|
||||
if (Inst.isAdd) OS << "|(1ULL<<MCID::Add)";
|
||||
if (Inst.isSelect) OS << "|(1ULL<<MCID::Select)";
|
||||
if (Inst.isBarrier) OS << "|(1ULL<<MCID::Barrier)";
|
||||
if (Inst.hasDelaySlot) OS << "|(1ULL<<MCID::DelaySlot)";
|
||||
|
|
Loading…
Reference in New Issue