summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-06-05 18:28:55 +0000
committerChris Lattner <sabre@nondot.org>2003-06-05 18:28:55 +0000
commit35333e16ee1d5154dc58ad38412be025d0d809ff (patch)
treefe9c5a46e5428e0abdea12231902b4eeb3c31177 /lib
parent76594014f2ce0a88b212d0ea4b7a939ab93c533c (diff)
downloadllvm-35333e16ee1d5154dc58ad38412be025d0d809ff.tar.gz
llvm-35333e16ee1d5154dc58ad38412be025d0d809ff.tar.bz2
llvm-35333e16ee1d5154dc58ad38412be025d0d809ff.tar.xz
Special case simple binary operator X op C
This avoid generating a register to hold C, which in turn speeds up the register allocator by a lot: ~9% on 164.gzip and ~17% on 256.bzip2. This also speeds up other passes. This also speeds up execution of the program marginally, and makes the asm much easier to read. :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6626 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/X86/InstSelectSimple.cpp82
-rw-r--r--lib/Target/X86/X86ISelSimple.cpp82
2 files changed, 110 insertions, 54 deletions
diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp
index b19c5c208e..f78c6f8bf4 100644
--- a/lib/Target/X86/InstSelectSimple.cpp
+++ b/lib/Target/X86/InstSelectSimple.cpp
@@ -983,36 +983,64 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *BB,
Value *Op0, Value *Op1,
unsigned OperatorClass,unsigned TargetReg){
unsigned Class = getClassB(Op0->getType());
+ if (!isa<ConstantInt>(Op1) || Class == cLong) {
+ static const unsigned OpcodeTab[][4] = {
+ // Arithmetic operators
+ { X86::ADDrr8, X86::ADDrr16, X86::ADDrr32, X86::FpADD }, // ADD
+ { X86::SUBrr8, X86::SUBrr16, X86::SUBrr32, X86::FpSUB }, // SUB
+
+ // Bitwise operators
+ { X86::ANDrr8, X86::ANDrr16, X86::ANDrr32, 0 }, // AND
+ { X86:: ORrr8, X86:: ORrr16, X86:: ORrr32, 0 }, // OR
+ { X86::XORrr8, X86::XORrr16, X86::XORrr32, 0 }, // XOR
+ };
+
+ bool isLong = false;
+ if (Class == cLong) {
+ isLong = true;
+ Class = cInt; // Bottom 32 bits are handled just like ints
+ }
+
+ unsigned Opcode = OpcodeTab[OperatorClass][Class];
+ assert(Opcode && "Floating point arguments to logical inst?");
+ unsigned Op0r = getReg(Op0, BB, IP);
+ unsigned Op1r = getReg(Op1, BB, IP);
+ BMI(BB, IP, Opcode, 2, TargetReg).addReg(Op0r).addReg(Op1r);
+
+ if (isLong) { // Handle the upper 32 bits of long values...
+ static const unsigned TopTab[] = {
+ X86::ADCrr32, X86::SBBrr32, X86::ANDrr32, X86::ORrr32, X86::XORrr32
+ };
+ BMI(BB, IP, TopTab[OperatorClass], 2,
+ TargetReg+1).addReg(Op0r+1).addReg(Op1r+1);
+ }
+ } else {
+ // Special case: op Reg, <const>
+ ConstantInt *Op1C = cast<ConstantInt>(Op1);
- static const unsigned OpcodeTab[][4] = {
- // Arithmetic operators
- { X86::ADDrr8, X86::ADDrr16, X86::ADDrr32, X86::FpADD }, // ADD
- { X86::SUBrr8, X86::SUBrr16, X86::SUBrr32, X86::FpSUB }, // SUB
+ static const unsigned OpcodeTab[][3] = {
+ // Arithmetic operators
+ { X86::ADDri8, X86::ADDri16, X86::ADDri32 }, // ADD
+ { X86::SUBri8, X86::SUBri16, X86::SUBri32 }, // SUB
+
+ // Bitwise operators
+ { X86::ANDri8, X86::ANDri16, X86::ANDri32 }, // AND
+ { X86:: ORri8, X86:: ORri16, X86:: ORri32 }, // OR
+ { X86::XORri8, X86::XORri16, X86::XORri32 }, // XOR
+ };
- // Bitwise operators
- { X86::ANDrr8, X86::ANDrr16, X86::ANDrr32, 0 }, // AND
- { X86:: ORrr8, X86:: ORrr16, X86:: ORrr32, 0 }, // OR
- { X86::XORrr8, X86::XORrr16, X86::XORrr32, 0 }, // XOR
- };
+ assert(Class < 3 && "General code handles 64-bit integer types!");
+ unsigned Opcode = OpcodeTab[OperatorClass][Class];
+ unsigned Op0r = getReg(Op0, BB, IP);
+ uint64_t Op1v;
+ if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op1C))
+ Op1v = CSI->getValue();
+ else
+ Op1v = cast<ConstantUInt>(Op1C)->getValue();
- bool isLong = false;
- if (Class == cLong) {
- isLong = true;
- Class = cInt; // Bottom 32 bits are handled just like ints
- }
-
- unsigned Opcode = OpcodeTab[OperatorClass][Class];
- assert(Opcode && "Floating point arguments to logical inst?");
- unsigned Op0r = getReg(Op0, BB, IP);
- unsigned Op1r = getReg(Op1, BB, IP);
- BMI(BB, IP, Opcode, 2, TargetReg).addReg(Op0r).addReg(Op1r);
-
- if (isLong) { // Handle the upper 32 bits of long values...
- static const unsigned TopTab[] = {
- X86::ADCrr32, X86::SBBrr32, X86::ANDrr32, X86::ORrr32, X86::XORrr32
- };
- BMI(BB, IP, TopTab[OperatorClass], 2,
- TargetReg+1).addReg(Op0r+1).addReg(Op1r+1);
+ // Mask off any upper bits of the constant, if there are any...
+ Op1v &= (1ULL << (8 << Class)) - 1;
+ BMI(BB, IP, Opcode, 2, TargetReg).addReg(Op0r).addZImm(Op1v);
}
}
diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp
index b19c5c208e..f78c6f8bf4 100644
--- a/lib/Target/X86/X86ISelSimple.cpp
+++ b/lib/Target/X86/X86ISelSimple.cpp
@@ -983,36 +983,64 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *BB,
Value *Op0, Value *Op1,
unsigned OperatorClass,unsigned TargetReg){
unsigned Class = getClassB(Op0->getType());
+ if (!isa<ConstantInt>(Op1) || Class == cLong) {
+ static const unsigned OpcodeTab[][4] = {
+ // Arithmetic operators
+ { X86::ADDrr8, X86::ADDrr16, X86::ADDrr32, X86::FpADD }, // ADD
+ { X86::SUBrr8, X86::SUBrr16, X86::SUBrr32, X86::FpSUB }, // SUB
+
+ // Bitwise operators
+ { X86::ANDrr8, X86::ANDrr16, X86::ANDrr32, 0 }, // AND
+ { X86:: ORrr8, X86:: ORrr16, X86:: ORrr32, 0 }, // OR
+ { X86::XORrr8, X86::XORrr16, X86::XORrr32, 0 }, // XOR
+ };
+
+ bool isLong = false;
+ if (Class == cLong) {
+ isLong = true;
+ Class = cInt; // Bottom 32 bits are handled just like ints
+ }
+
+ unsigned Opcode = OpcodeTab[OperatorClass][Class];
+ assert(Opcode && "Floating point arguments to logical inst?");
+ unsigned Op0r = getReg(Op0, BB, IP);
+ unsigned Op1r = getReg(Op1, BB, IP);
+ BMI(BB, IP, Opcode, 2, TargetReg).addReg(Op0r).addReg(Op1r);
+
+ if (isLong) { // Handle the upper 32 bits of long values...
+ static const unsigned TopTab[] = {
+ X86::ADCrr32, X86::SBBrr32, X86::ANDrr32, X86::ORrr32, X86::XORrr32
+ };
+ BMI(BB, IP, TopTab[OperatorClass], 2,
+ TargetReg+1).addReg(Op0r+1).addReg(Op1r+1);
+ }
+ } else {
+ // Special case: op Reg, <const>
+ ConstantInt *Op1C = cast<ConstantInt>(Op1);
- static const unsigned OpcodeTab[][4] = {
- // Arithmetic operators
- { X86::ADDrr8, X86::ADDrr16, X86::ADDrr32, X86::FpADD }, // ADD
- { X86::SUBrr8, X86::SUBrr16, X86::SUBrr32, X86::FpSUB }, // SUB
+ static const unsigned OpcodeTab[][3] = {
+ // Arithmetic operators
+ { X86::ADDri8, X86::ADDri16, X86::ADDri32 }, // ADD
+ { X86::SUBri8, X86::SUBri16, X86::SUBri32 }, // SUB
+
+ // Bitwise operators
+ { X86::ANDri8, X86::ANDri16, X86::ANDri32 }, // AND
+ { X86:: ORri8, X86:: ORri16, X86:: ORri32 }, // OR
+ { X86::XORri8, X86::XORri16, X86::XORri32 }, // XOR
+ };
- // Bitwise operators
- { X86::ANDrr8, X86::ANDrr16, X86::ANDrr32, 0 }, // AND
- { X86:: ORrr8, X86:: ORrr16, X86:: ORrr32, 0 }, // OR
- { X86::XORrr8, X86::XORrr16, X86::XORrr32, 0 }, // XOR
- };
+ assert(Class < 3 && "General code handles 64-bit integer types!");
+ unsigned Opcode = OpcodeTab[OperatorClass][Class];
+ unsigned Op0r = getReg(Op0, BB, IP);
+ uint64_t Op1v;
+ if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op1C))
+ Op1v = CSI->getValue();
+ else
+ Op1v = cast<ConstantUInt>(Op1C)->getValue();
- bool isLong = false;
- if (Class == cLong) {
- isLong = true;
- Class = cInt; // Bottom 32 bits are handled just like ints
- }
-
- unsigned Opcode = OpcodeTab[OperatorClass][Class];
- assert(Opcode && "Floating point arguments to logical inst?");
- unsigned Op0r = getReg(Op0, BB, IP);
- unsigned Op1r = getReg(Op1, BB, IP);
- BMI(BB, IP, Opcode, 2, TargetReg).addReg(Op0r).addReg(Op1r);
-
- if (isLong) { // Handle the upper 32 bits of long values...
- static const unsigned TopTab[] = {
- X86::ADCrr32, X86::SBBrr32, X86::ANDrr32, X86::ORrr32, X86::XORrr32
- };
- BMI(BB, IP, TopTab[OperatorClass], 2,
- TargetReg+1).addReg(Op0r+1).addReg(Op1r+1);
+ // Mask off any upper bits of the constant, if there are any...
+ Op1v &= (1ULL << (8 << Class)) - 1;
+ BMI(BB, IP, Opcode, 2, TargetReg).addReg(Op0r).addZImm(Op1v);
}
}