diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-07-10 01:54:42 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-07-10 01:54:42 +0000 |
commit | 06e16587ebc81e43b42157fa3afcfd806b59b296 (patch) | |
tree | 76e4f27ee3b197064487715c71ed7fbb7275d58f /lib | |
parent | ab331504452a833f27a030f13525b964545d768a (diff) |
Add a thumb2 pass to insert IT blocks.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75218 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/ARM.h | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb.td | 9 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 16 | ||||
-rw-r--r-- | lib/Target/ARM/ARMTargetMachine.cpp | 3 | ||||
-rw-r--r-- | lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb2ITBlockPass.cpp | 108 |
6 files changed, 130 insertions, 10 deletions
diff --git a/lib/Target/ARM/ARM.h b/lib/Target/ARM/ARM.h index 12c26e8c79..0e654d8e64 100644 --- a/lib/Target/ARM/ARM.h +++ b/lib/Target/ARM/ARM.h @@ -108,6 +108,8 @@ FunctionPass *createARMObjectCodeEmitterPass(ARMBaseTargetMachine &TM, FunctionPass *createARMLoadStoreOptimizationPass(bool PreAlloc = false); FunctionPass *createARMConstantIslandPass(); +FunctionPass *createThumb2ITBlockPass(); + } // end namespace llvm; // Defines symbolic names for ARM registers. This defines a mapping from diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 5642710b5c..fb7453a912 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -66,11 +66,6 @@ def thumb_immshifted_shamt : SDNodeXForm<imm, [{ return CurDAG->getTargetConstant(V, MVT::i32); }]>; -// IT block condition mask -def it_mask : Operand<i32> { - let PrintMethod = "printThumbITMask"; -} - // Define Thumb specific addressing modes. // t_addrmode_rr := reg + reg @@ -212,10 +207,6 @@ let isBranch = 1, isTerminator = 1 in def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), "b$cc $target", [/*(ARMbrcond bb:$target, imm:$cc)*/]>; -// IT block -def tIT : TI<(outs), (ins pred:$cc, it_mask:$mask), - "it$mask $cc", []>; - //===----------------------------------------------------------------------===// // Load Store Instructions. // diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index be73831072..34ce53f97f 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -11,6 +11,16 @@ // //===----------------------------------------------------------------------===// +// IT block predicate field +def it_pred : Operand<i32> { + let PrintMethod = "printPredicateOperand"; +} + +// IT block condition mask +def it_mask : Operand<i32> { + let PrintMethod = "printThumbITMask"; +} + // Shifted operands. No register controlled shifts for Thumb2. // Note: We do not support rrx shifted operands yet. def t2_so_reg : Operand<i32>, // reg imm @@ -1121,6 +1131,12 @@ def t2Bcc : T2I<(outs), (ins brtarget:$target), "b", " $target", [/*(ARMbrcond bb:$target, imm:$cc)*/]>; + +// IT block +def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask), + AddrModeNone, Size2Bytes, + "it$mask $cc", "", []>; + //===----------------------------------------------------------------------===// // Non-Instruction Patterns // diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp index b3faadafc5..a827784383 100644 --- a/lib/Target/ARM/ARMTargetMachine.cpp +++ b/lib/Target/ARM/ARMTargetMachine.cpp @@ -173,6 +173,9 @@ bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM, !DisableIfConversion && !Subtarget.isThumb()) PM.add(createIfConverterPass()); + if (Subtarget.isThumb2()) + PM.add(createThumb2ITBlockPass()); + PM.add(createARMConstantIslandPass()); return true; } diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp index b298ff7715..3b1c491ef1 100644 --- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp @@ -642,7 +642,7 @@ ARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op) { unsigned Mask = MI->getOperand(Op).getImm(); unsigned NumTZ = CountTrailingZeros_32(Mask); assert(NumTZ <= 3 && "Invalid IT mask!"); - for (unsigned Pos = 3, e = NumTZ; Pos >= e; --Pos) { + for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) { bool T = (Mask & (1 << Pos)) != 0; if (T) O << 't'; diff --git a/lib/Target/ARM/Thumb2ITBlockPass.cpp b/lib/Target/ARM/Thumb2ITBlockPass.cpp new file mode 100644 index 0000000000..f6f75a1a4b --- /dev/null +++ b/lib/Target/ARM/Thumb2ITBlockPass.cpp @@ -0,0 +1,108 @@ +//===-- Thumb2ITBlockPass.cpp - Insert Thumb IT blocks -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "thumb2-it" +#include "ARM.h" +#include "ARMInstrInfo.h" +#include "ARMMachineFunctionInfo.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/Support/Compiler.h" +#include "llvm/ADT/Statistic.h" +using namespace llvm; + +STATISTIC(NumITs, "Number of IT blocks inserted"); + +namespace { + struct VISIBILITY_HIDDEN Thumb2ITBlockPass : public MachineFunctionPass { + static char ID; + Thumb2ITBlockPass() : MachineFunctionPass(&ID) {} + + const ARMBaseInstrInfo *TII; + ARMFunctionInfo *AFI; + + virtual bool runOnMachineFunction(MachineFunction &Fn); + + virtual const char *getPassName() const { + return "Thumb IT blocks insertion pass"; + } + + private: + bool InsertITBlocks(MachineBasicBlock &MBB); + }; + char Thumb2ITBlockPass::ID = 0; +} + +bool Thumb2ITBlockPass::InsertITBlocks(MachineBasicBlock &MBB) { + bool Modified = false; + + MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); + while (MBBI != E) { + MachineInstr *MI = &*MBBI; + ARMCC::CondCodes CC = TII->getPredicate(MI); + if (CC == ARMCC::AL) { + ++MBBI; + continue; + } + + // Insert an IT instruction. + DebugLoc dl = MI->getDebugLoc(); + MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT)) + .addImm(CC); + ++MBBI; + + // Finalize IT mask. If the following instruction is not predicated or it's + // predicated on a condition that's not the same or the opposite of CC, then + // the mask is 0x8. + ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC); + unsigned Mask = 0x8; + while (MBBI != E || (Mask & 1)) { + ARMCC::CondCodes NCC = TII->getPredicate(&*MBBI); + if (NCC == CC) { + Mask >>= 1; + Mask |= 0x8; + } else if (NCC == OCC) { + Mask >>= 1; + } else { + break; + } + ++MBBI; + } + MIB.addImm(Mask); + Modified = true; + ++NumITs; + } + + return Modified; +} + +bool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction &Fn) { + const TargetMachine &TM = Fn.getTarget(); + AFI = Fn.getInfo<ARMFunctionInfo>(); + TII = static_cast<const ARMBaseInstrInfo*>(TM.getInstrInfo()); + + if (!AFI->isThumbFunction()) + return false; + + bool Modified = false; + for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; + ++MFI) { + MachineBasicBlock &MBB = *MFI; + Modified |= InsertITBlocks(MBB); + } + + return Modified; +} + +/// createThumb2ITBlockPass - returns and instance of the Thumb IT blocks +/// insertion pass. +FunctionPass *llvm::createThumb2ITBlockPass() { + return new Thumb2ITBlockPass(); +} |