summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-08-10 16:34:52 +0000
committerChris Lattner <sabre@nondot.org>2005-08-10 16:34:52 +0000
commit67d0753773d3cac492b9caeb474c69721696d915 (patch)
treee94524af9ac1186026735d21b00a04b883f7eaf5 /llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
parent1c2f9fdf71f7b99aa871131006b0d0713cf917ce (diff)
downloadbcm5719-llvm-67d0753773d3cac492b9caeb474c69721696d915.tar.gz
bcm5719-llvm-67d0753773d3cac492b9caeb474c69721696d915.zip
1. Refactored handling of integer immediate values for add, or, xor and sub.
New routine: ISel::SelectIntImmediateExpr 2. Now checking use counts of large constants. If use count is > 2 then drop thru so that the constant gets loaded into a register. Source: int %test1(int %a) { entry: %tmp.1 = add int %a, 123456789 ; <int> [#uses=1] %tmp.2 = or int %tmp.1, 123456789 ; <int> [#uses=1] %tmp.3 = xor int %tmp.2, 123456789 ; <int> [#uses=1] %tmp.4 = sub int %tmp.3, -123456789 ; <int> [#uses=1] ret int %tmp.4 } Did Emit: .machine ppc970 .text .align 2 .globl _test1 _test1: .LBB_test1_0: ; entry addi r2, r3, -13035 addis r2, r2, 1884 ori r2, r2, 52501 oris r2, r2, 1883 xori r2, r2, 52501 xoris r2, r2, 1883 addi r2, r2, 52501 addis r3, r2, 1883 blr Now Emits: .machine ppc970 .text .align 2 .globl _test1 _test1: .LBB_test1_0: ; entry lis r2, 1883 ori r2, r2, 52501 add r3, r3, r2 or r3, r3, r2 xor r3, r3, r2 add r3, r3, r2 blr Patch by Jim Laskey! llvm-svn: 22749
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp')
-rw-r--r--llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp121
1 files changed, 61 insertions, 60 deletions
diff --git a/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp b/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
index 095afc647a9..49bbeb0a59b 100644
--- a/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
+++ b/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
@@ -569,6 +569,9 @@ public:
unsigned FoldIfWideZeroExtend(SDOperand N);
unsigned SelectCC(SDOperand CC, unsigned &Opc, bool &Inv, unsigned &Idx);
unsigned SelectCCExpr(SDOperand N, unsigned& Opc, bool &Inv, unsigned &Idx);
+ bool SelectIntImmediateExpr(SDOperand N, unsigned Result, unsigned C,
+ unsigned OCHi, unsigned OCLo,
+ bool IsArithmetic);
unsigned SelectExpr(SDOperand N, bool Recording=false);
void Select(SDOperand N);
@@ -1275,6 +1278,45 @@ void ISel::SelectBranchCC(SDOperand N)
return;
}
+// SelectIntImmediateExpr - Choose code for opcodes with immediate value.
+// Note: immediate constant must be second operand so that the use count can be
+// determined.
+bool ISel::SelectIntImmediateExpr(SDOperand N, unsigned Result, unsigned C,
+ unsigned OCHi, unsigned OCLo,
+ bool IsArithmetic) {
+ // get the hi and lo portions of constant
+ unsigned Hi = IsArithmetic ? HA16(C) : Hi16(C);
+ unsigned Lo = Lo16(C);
+ // assume no intermediate result from lo instruction (same as final result)
+ unsigned Tmp = Result;
+ // check if two instructions are needed
+ if (Hi && Lo) {
+ // exit if usage indicates it would be better to load immediate into a
+ // register
+ if (dyn_cast<ConstantSDNode>(N.getOperand(1))->use_size() > 2)
+ return false;
+ // need intermediate result for two instructions
+ Tmp = MakeReg(MVT::i32);
+ }
+ // get first operand
+ unsigned Opr0 = SelectExpr(N.getOperand(0));
+ // is a lo instruction needed
+ if (Lo) {
+ // generate instruction for hi portion
+ const MachineInstrBuilder &MIBLo = BuildMI(BB, OCLo, 2, Tmp).addReg(Opr0);
+ if (IsArithmetic) MIBLo.addSImm(Lo); else MIBLo.addImm(Lo);
+ // need to switch out first operand for hi instruction
+ Opr0 = Tmp;
+ }
+ // is a ho instruction needed
+ if (Hi) {
+ // generate instruction for hi portion
+ const MachineInstrBuilder &MIBHi = BuildMI(BB, OCHi, 2, Result).addReg(Opr0);
+ if (IsArithmetic) MIBHi.addSImm(Hi); else MIBHi.addImm(Hi);
+ }
+ return true;
+}
+
unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
unsigned Result;
unsigned Tmp1, Tmp2, Tmp3;
@@ -1636,22 +1678,12 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
return Result;
}
- Tmp1 = SelectExpr(N.getOperand(0));
if (isIntImmediate(N.getOperand(1), Tmp2)) {
- Tmp3 = HA16(Tmp2);
- Tmp2 = Lo16(Tmp2);
- if (Tmp2 && Tmp3) {
- unsigned Reg = MakeReg(MVT::i32);
- BuildMI(BB, PPC::ADDI, 2, Reg).addReg(Tmp1).addSImm(Tmp2);
- BuildMI(BB, PPC::ADDIS, 2, Result).addReg(Reg).addSImm(Tmp3);
- } else if (Tmp2) {
- BuildMI(BB, PPC::ADDI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
- } else {
- BuildMI(BB, PPC::ADDIS, 2, Result).addReg(Tmp1).addSImm(Tmp3);
- }
- return Result;
+ if (SelectIntImmediateExpr(N, Result, Tmp2, PPC::ADDIS, PPC::ADDI, true))
+ return Result;
}
+ Tmp1 = SelectExpr(N.getOperand(0));
Tmp2 = SelectExpr(N.getOperand(1));
BuildMI(BB, PPC::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2);
return Result;
@@ -1706,26 +1738,16 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
case ISD::OR:
if (SelectBitfieldInsert(N, Result))
return Result;
-
- Tmp1 = SelectExpr(N.getOperand(0));
if (isIntImmediate(N.getOperand(1), Tmp2)) {
- Tmp3 = Hi16(Tmp2);
- Tmp2 = Lo16(Tmp2);
- if (Tmp2 && Tmp3) {
- unsigned Reg = MakeReg(MVT::i32);
- BuildMI(BB, PPC::ORI, 2, Reg).addReg(Tmp1).addImm(Tmp2);
- BuildMI(BB, PPC::ORIS, 2, Result).addReg(Reg).addImm(Tmp3);
- } else if (Tmp2) {
- BuildMI(BB, PPC::ORI, 2, Result).addReg(Tmp1).addImm(Tmp2);
- } else {
- BuildMI(BB, PPC::ORIS, 2, Result).addReg(Tmp1).addImm(Tmp3);
- }
- } else {
- Tmp2 = SelectExpr(N.getOperand(1));
- Opc = Recording ? PPC::ORo : PPC::OR;
- RecordSuccess = true;
- BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
+ if (SelectIntImmediateExpr(N, Result, Tmp2, PPC::ORIS, PPC::ORI, false))
+ return Result;
}
+ // emit regular or
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ Opc = Recording ? PPC::ORo : PPC::OR;
+ RecordSuccess = true;
+ BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
return Result;
case ISD::XOR: {
@@ -1763,23 +1785,14 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
}
return Result;
}
- Tmp1 = SelectExpr(N.getOperand(0));
if (isIntImmediate(N.getOperand(1), Tmp2)) {
- Tmp3 = Hi16(Tmp2);
- Tmp2 = Lo16(Tmp2);
- if (Tmp2 && Tmp3) {
- unsigned Reg = MakeReg(MVT::i32);
- BuildMI(BB, PPC::XORI, 2, Reg).addReg(Tmp1).addImm(Tmp2);
- BuildMI(BB, PPC::XORIS, 2, Result).addReg(Reg).addImm(Tmp3);
- } else if (Tmp2) {
- BuildMI(BB, PPC::XORI, 2, Result).addReg(Tmp1).addImm(Tmp2);
- } else {
- BuildMI(BB, PPC::XORIS, 2, Result).addReg(Tmp1).addImm(Tmp3);
- }
- } else {
- Tmp2 = SelectExpr(N.getOperand(1));
- BuildMI(BB, PPC::XOR, 2, Result).addReg(Tmp1).addReg(Tmp2);
+ if (SelectIntImmediateExpr(N, Result, Tmp2, PPC::XORIS, PPC::XORI, false))
+ return Result;
}
+ // emit regular xor
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ BuildMI(BB, PPC::XOR, 2, Result).addReg(Tmp1).addReg(Tmp2);
return Result;
}
@@ -1816,20 +1829,8 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp2).addSImm(Tmp1);
return Result;
} else if (isIntImmediate(N.getOperand(1), Tmp2)) {
- Tmp1 = SelectExpr(N.getOperand(0));
- Tmp2 = -Tmp2;
- Tmp3 = HA16(Tmp2);
- Tmp2 = Lo16(Tmp2);
- if (Tmp2 && Tmp3) {
- unsigned Reg = MakeReg(MVT::i32);
- BuildMI(BB, PPC::ADDI, 2, Reg).addReg(Tmp1).addSImm(Tmp2);
- BuildMI(BB, PPC::ADDIS, 2, Result).addReg(Reg).addSImm(Tmp3);
- } else if (Tmp2) {
- BuildMI(BB, PPC::ADDI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
- } else {
- BuildMI(BB, PPC::ADDIS, 2, Result).addReg(Tmp1).addSImm(Tmp3);
- }
- return Result;
+ if (SelectIntImmediateExpr(N, Result, -Tmp2, PPC::ADDIS, PPC::ADDI, true))
+ return Result;
}
Tmp1 = SelectExpr(N.getOperand(0));
Tmp2 = SelectExpr(N.getOperand(1));
OpenPOWER on IntegriCloud