diff options
author | Chris Lattner <sabre@nondot.org> | 2003-06-05 18:28:55 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-06-05 18:28:55 +0000 |
commit | 35333e16ee1d5154dc58ad38412be025d0d809ff (patch) | |
tree | fe9c5a46e5428e0abdea12231902b4eeb3c31177 /lib | |
parent | 76594014f2ce0a88b212d0ea4b7a939ab93c533c (diff) | |
download | external_llvm-35333e16ee1d5154dc58ad38412be025d0d809ff.zip external_llvm-35333e16ee1d5154dc58ad38412be025d0d809ff.tar.gz external_llvm-35333e16ee1d5154dc58ad38412be025d0d809ff.tar.bz2 |
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.cpp | 82 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelSimple.cpp | 82 |
2 files changed, 110 insertions, 54 deletions
diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index b19c5c2..f78c6f8 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 b19c5c2..f78c6f8 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); } } |