1//===-- Thumb2SizeReduction.cpp - Thumb2 code size reduction pass -*- C++ -*-=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#define DEBUG_TYPE "t2-reduce-size" 11#include "ARM.h" 12#include "ARMAddressingModes.h" 13#include "ARMBaseRegisterInfo.h" 14#include "ARMBaseInstrInfo.h" 15#include "Thumb2InstrInfo.h" 16#include "llvm/CodeGen/MachineInstr.h" 17#include "llvm/CodeGen/MachineInstrBuilder.h" 18#include "llvm/CodeGen/MachineFunctionPass.h" 19#include "llvm/Support/CommandLine.h" 20#include "llvm/Support/Debug.h" 21#include "llvm/Support/raw_ostream.h" 22#include "llvm/ADT/DenseMap.h" 23#include "llvm/ADT/Statistic.h" 24using namespace llvm; 25 26STATISTIC(NumNarrows, "Number of 32-bit instrs reduced to 16-bit ones"); 27STATISTIC(Num2Addrs, "Number of 32-bit instrs reduced to 2addr 16-bit ones"); 28STATISTIC(NumLdSts, "Number of 32-bit load / store reduced to 16-bit ones"); 29 30static cl::opt<int> ReduceLimit("t2-reduce-limit", 31 cl::init(-1), cl::Hidden); 32static cl::opt<int> ReduceLimit2Addr("t2-reduce-limit2", 33 cl::init(-1), cl::Hidden); 34static cl::opt<int> ReduceLimitLdSt("t2-reduce-limit3", 35 cl::init(-1), cl::Hidden); 36 37namespace { 38 /// ReduceTable - A static table with information on mapping from wide 39 /// opcodes to narrow 40 struct ReduceEntry { 41 unsigned WideOpc; // Wide opcode 42 unsigned NarrowOpc1; // Narrow opcode to transform to 43 unsigned NarrowOpc2; // Narrow opcode when it's two-address 44 uint8_t Imm1Limit; // Limit of immediate field (bits) 45 uint8_t Imm2Limit; // Limit of immediate field when it's two-address 46 unsigned LowRegs1 : 1; // Only possible if low-registers are used 47 unsigned LowRegs2 : 1; // Only possible if low-registers are used (2addr) 48 unsigned PredCC1 : 2; // 0 - If predicated, cc is on and vice versa. 49 // 1 - No cc field. 50 // 2 - Always set CPSR. 51 unsigned PredCC2 : 2; 52 unsigned Special : 1; // Needs to be dealt with specially 53 }; 54 55 static const ReduceEntry ReduceTable[] = { 56 // Wide, Narrow1, Narrow2, imm1,imm2, lo1, lo2, P/C, S 57 { ARM::t2ADCrr, 0, ARM::tADC, 0, 0, 0, 1, 0,0, 0 }, 58 { ARM::t2ADDri, ARM::tADDi3, ARM::tADDi8, 3, 8, 1, 1, 0,0, 0 }, 59 { ARM::t2ADDrr, ARM::tADDrr, ARM::tADDhirr, 0, 0, 1, 0, 0,1, 0 }, 60 // Note: immediate scale is 4. 61 { ARM::t2ADDrSPi,ARM::tADDrSPi,0, 8, 0, 1, 0, 1,0, 0 }, 62 { ARM::t2ADDSri,ARM::tADDi3, ARM::tADDi8, 3, 8, 1, 1, 2,2, 1 }, 63 { ARM::t2ADDSrr,ARM::tADDrr, 0, 0, 0, 1, 0, 2,0, 1 }, 64 { ARM::t2ANDrr, 0, ARM::tAND, 0, 0, 0, 1, 0,0, 0 }, 65 { ARM::t2ASRri, ARM::tASRri, 0, 5, 0, 1, 0, 0,0, 0 }, 66 { ARM::t2ASRrr, 0, ARM::tASRrr, 0, 0, 0, 1, 0,0, 0 }, 67 { ARM::t2BICrr, 0, ARM::tBIC, 0, 0, 0, 1, 0,0, 0 }, 68 { ARM::t2CMNrr, ARM::tCMN, 0, 0, 0, 1, 0, 2,0, 0 }, 69 { ARM::t2CMPri, ARM::tCMPi8, 0, 8, 0, 1, 0, 2,0, 0 }, 70 { ARM::t2CMPrr, ARM::tCMPhir, 0, 0, 0, 0, 0, 2,0, 0 }, 71 { ARM::t2CMPzri,ARM::tCMPzi8, 0, 8, 0, 1, 0, 2,0, 0 }, 72 { ARM::t2CMPzrr,ARM::tCMPzhir,0, 0, 0, 0, 0, 2,0, 0 }, 73 { ARM::t2EORrr, 0, ARM::tEOR, 0, 0, 0, 1, 0,0, 0 }, 74 // FIXME: adr.n immediate offset must be multiple of 4. 75 //{ ARM::t2LEApcrelJT,ARM::tLEApcrelJT, 0, 0, 0, 1, 0, 1,0, 0 }, 76 { ARM::t2LSLri, ARM::tLSLri, 0, 5, 0, 1, 0, 0,0, 0 }, 77 { ARM::t2LSLrr, 0, ARM::tLSLrr, 0, 0, 0, 1, 0,0, 0 }, 78 { ARM::t2LSRri, ARM::tLSRri, 0, 5, 0, 1, 0, 0,0, 0 }, 79 { ARM::t2LSRrr, 0, ARM::tLSRrr, 0, 0, 0, 1, 0,0, 0 }, 80 { ARM::t2MOVi, ARM::tMOVi8, 0, 8, 0, 1, 0, 0,0, 0 }, 81 { ARM::t2MOVi16,ARM::tMOVi8, 0, 8, 0, 1, 0, 0,0, 0 }, 82 // FIXME: Do we need the 16-bit 'S' variant? 83 { ARM::t2MOVr,ARM::tMOVgpr2gpr,0, 0, 0, 0, 0, 1,0, 0 }, 84 { ARM::t2MOVCCr,0, ARM::tMOVCCr, 0, 0, 0, 0, 0,1, 0 }, 85 { ARM::t2MOVCCi,0, ARM::tMOVCCi, 0, 8, 0, 0, 0,1, 0 }, 86 { ARM::t2MUL, 0, ARM::tMUL, 0, 0, 0, 1, 0,0, 0 }, 87 { ARM::t2MVNr, ARM::tMVN, 0, 0, 0, 1, 0, 0,0, 0 }, 88 { ARM::t2ORRrr, 0, ARM::tORR, 0, 0, 0, 1, 0,0, 0 }, 89 { ARM::t2REV, ARM::tREV, 0, 0, 0, 1, 0, 1,0, 0 }, 90 { ARM::t2REV16, ARM::tREV16, 0, 0, 0, 1, 0, 1,0, 0 }, 91 { ARM::t2REVSH, ARM::tREVSH, 0, 0, 0, 1, 0, 1,0, 0 }, 92 { ARM::t2RORrr, 0, ARM::tROR, 0, 0, 0, 1, 0,0, 0 }, 93 { ARM::t2RSBri, ARM::tRSB, 0, 0, 0, 1, 0, 0,0, 1 }, 94 { ARM::t2RSBSri,ARM::tRSB, 0, 0, 0, 1, 0, 2,0, 1 }, 95 { ARM::t2SBCrr, 0, ARM::tSBC, 0, 0, 0, 1, 0,0, 0 }, 96 { ARM::t2SUBri, ARM::tSUBi3, ARM::tSUBi8, 3, 8, 1, 1, 0,0, 0 }, 97 { ARM::t2SUBrr, ARM::tSUBrr, 0, 0, 0, 1, 0, 0,0, 0 }, 98 { ARM::t2SUBSri,ARM::tSUBi3, ARM::tSUBi8, 3, 8, 1, 1, 2,2, 0 }, 99 { ARM::t2SUBSrr,ARM::tSUBrr, 0, 0, 0, 1, 0, 2,0, 0 }, 100 { ARM::t2SXTBr, ARM::tSXTB, 0, 0, 0, 1, 0, 1,0, 0 }, 101 { ARM::t2SXTHr, ARM::tSXTH, 0, 0, 0, 1, 0, 1,0, 0 }, 102 { ARM::t2TSTrr, ARM::tTST, 0, 0, 0, 1, 0, 2,0, 0 }, 103 { ARM::t2UXTBr, ARM::tUXTB, 0, 0, 0, 1, 0, 1,0, 0 }, 104 { ARM::t2UXTHr, ARM::tUXTH, 0, 0, 0, 1, 0, 1,0, 0 }, 105 106 // FIXME: Clean this up after splitting each Thumb load / store opcode 107 // into multiple ones.
| 1//===-- Thumb2SizeReduction.cpp - Thumb2 code size reduction pass -*- C++ -*-=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#define DEBUG_TYPE "t2-reduce-size" 11#include "ARM.h" 12#include "ARMAddressingModes.h" 13#include "ARMBaseRegisterInfo.h" 14#include "ARMBaseInstrInfo.h" 15#include "Thumb2InstrInfo.h" 16#include "llvm/CodeGen/MachineInstr.h" 17#include "llvm/CodeGen/MachineInstrBuilder.h" 18#include "llvm/CodeGen/MachineFunctionPass.h" 19#include "llvm/Support/CommandLine.h" 20#include "llvm/Support/Debug.h" 21#include "llvm/Support/raw_ostream.h" 22#include "llvm/ADT/DenseMap.h" 23#include "llvm/ADT/Statistic.h" 24using namespace llvm; 25 26STATISTIC(NumNarrows, "Number of 32-bit instrs reduced to 16-bit ones"); 27STATISTIC(Num2Addrs, "Number of 32-bit instrs reduced to 2addr 16-bit ones"); 28STATISTIC(NumLdSts, "Number of 32-bit load / store reduced to 16-bit ones"); 29 30static cl::opt<int> ReduceLimit("t2-reduce-limit", 31 cl::init(-1), cl::Hidden); 32static cl::opt<int> ReduceLimit2Addr("t2-reduce-limit2", 33 cl::init(-1), cl::Hidden); 34static cl::opt<int> ReduceLimitLdSt("t2-reduce-limit3", 35 cl::init(-1), cl::Hidden); 36 37namespace { 38 /// ReduceTable - A static table with information on mapping from wide 39 /// opcodes to narrow 40 struct ReduceEntry { 41 unsigned WideOpc; // Wide opcode 42 unsigned NarrowOpc1; // Narrow opcode to transform to 43 unsigned NarrowOpc2; // Narrow opcode when it's two-address 44 uint8_t Imm1Limit; // Limit of immediate field (bits) 45 uint8_t Imm2Limit; // Limit of immediate field when it's two-address 46 unsigned LowRegs1 : 1; // Only possible if low-registers are used 47 unsigned LowRegs2 : 1; // Only possible if low-registers are used (2addr) 48 unsigned PredCC1 : 2; // 0 - If predicated, cc is on and vice versa. 49 // 1 - No cc field. 50 // 2 - Always set CPSR. 51 unsigned PredCC2 : 2; 52 unsigned Special : 1; // Needs to be dealt with specially 53 }; 54 55 static const ReduceEntry ReduceTable[] = { 56 // Wide, Narrow1, Narrow2, imm1,imm2, lo1, lo2, P/C, S 57 { ARM::t2ADCrr, 0, ARM::tADC, 0, 0, 0, 1, 0,0, 0 }, 58 { ARM::t2ADDri, ARM::tADDi3, ARM::tADDi8, 3, 8, 1, 1, 0,0, 0 }, 59 { ARM::t2ADDrr, ARM::tADDrr, ARM::tADDhirr, 0, 0, 1, 0, 0,1, 0 }, 60 // Note: immediate scale is 4. 61 { ARM::t2ADDrSPi,ARM::tADDrSPi,0, 8, 0, 1, 0, 1,0, 0 }, 62 { ARM::t2ADDSri,ARM::tADDi3, ARM::tADDi8, 3, 8, 1, 1, 2,2, 1 }, 63 { ARM::t2ADDSrr,ARM::tADDrr, 0, 0, 0, 1, 0, 2,0, 1 }, 64 { ARM::t2ANDrr, 0, ARM::tAND, 0, 0, 0, 1, 0,0, 0 }, 65 { ARM::t2ASRri, ARM::tASRri, 0, 5, 0, 1, 0, 0,0, 0 }, 66 { ARM::t2ASRrr, 0, ARM::tASRrr, 0, 0, 0, 1, 0,0, 0 }, 67 { ARM::t2BICrr, 0, ARM::tBIC, 0, 0, 0, 1, 0,0, 0 }, 68 { ARM::t2CMNrr, ARM::tCMN, 0, 0, 0, 1, 0, 2,0, 0 }, 69 { ARM::t2CMPri, ARM::tCMPi8, 0, 8, 0, 1, 0, 2,0, 0 }, 70 { ARM::t2CMPrr, ARM::tCMPhir, 0, 0, 0, 0, 0, 2,0, 0 }, 71 { ARM::t2CMPzri,ARM::tCMPzi8, 0, 8, 0, 1, 0, 2,0, 0 }, 72 { ARM::t2CMPzrr,ARM::tCMPzhir,0, 0, 0, 0, 0, 2,0, 0 }, 73 { ARM::t2EORrr, 0, ARM::tEOR, 0, 0, 0, 1, 0,0, 0 }, 74 // FIXME: adr.n immediate offset must be multiple of 4. 75 //{ ARM::t2LEApcrelJT,ARM::tLEApcrelJT, 0, 0, 0, 1, 0, 1,0, 0 }, 76 { ARM::t2LSLri, ARM::tLSLri, 0, 5, 0, 1, 0, 0,0, 0 }, 77 { ARM::t2LSLrr, 0, ARM::tLSLrr, 0, 0, 0, 1, 0,0, 0 }, 78 { ARM::t2LSRri, ARM::tLSRri, 0, 5, 0, 1, 0, 0,0, 0 }, 79 { ARM::t2LSRrr, 0, ARM::tLSRrr, 0, 0, 0, 1, 0,0, 0 }, 80 { ARM::t2MOVi, ARM::tMOVi8, 0, 8, 0, 1, 0, 0,0, 0 }, 81 { ARM::t2MOVi16,ARM::tMOVi8, 0, 8, 0, 1, 0, 0,0, 0 }, 82 // FIXME: Do we need the 16-bit 'S' variant? 83 { ARM::t2MOVr,ARM::tMOVgpr2gpr,0, 0, 0, 0, 0, 1,0, 0 }, 84 { ARM::t2MOVCCr,0, ARM::tMOVCCr, 0, 0, 0, 0, 0,1, 0 }, 85 { ARM::t2MOVCCi,0, ARM::tMOVCCi, 0, 8, 0, 0, 0,1, 0 }, 86 { ARM::t2MUL, 0, ARM::tMUL, 0, 0, 0, 1, 0,0, 0 }, 87 { ARM::t2MVNr, ARM::tMVN, 0, 0, 0, 1, 0, 0,0, 0 }, 88 { ARM::t2ORRrr, 0, ARM::tORR, 0, 0, 0, 1, 0,0, 0 }, 89 { ARM::t2REV, ARM::tREV, 0, 0, 0, 1, 0, 1,0, 0 }, 90 { ARM::t2REV16, ARM::tREV16, 0, 0, 0, 1, 0, 1,0, 0 }, 91 { ARM::t2REVSH, ARM::tREVSH, 0, 0, 0, 1, 0, 1,0, 0 }, 92 { ARM::t2RORrr, 0, ARM::tROR, 0, 0, 0, 1, 0,0, 0 }, 93 { ARM::t2RSBri, ARM::tRSB, 0, 0, 0, 1, 0, 0,0, 1 }, 94 { ARM::t2RSBSri,ARM::tRSB, 0, 0, 0, 1, 0, 2,0, 1 }, 95 { ARM::t2SBCrr, 0, ARM::tSBC, 0, 0, 0, 1, 0,0, 0 }, 96 { ARM::t2SUBri, ARM::tSUBi3, ARM::tSUBi8, 3, 8, 1, 1, 0,0, 0 }, 97 { ARM::t2SUBrr, ARM::tSUBrr, 0, 0, 0, 1, 0, 0,0, 0 }, 98 { ARM::t2SUBSri,ARM::tSUBi3, ARM::tSUBi8, 3, 8, 1, 1, 2,2, 0 }, 99 { ARM::t2SUBSrr,ARM::tSUBrr, 0, 0, 0, 1, 0, 2,0, 0 }, 100 { ARM::t2SXTBr, ARM::tSXTB, 0, 0, 0, 1, 0, 1,0, 0 }, 101 { ARM::t2SXTHr, ARM::tSXTH, 0, 0, 0, 1, 0, 1,0, 0 }, 102 { ARM::t2TSTrr, ARM::tTST, 0, 0, 0, 1, 0, 2,0, 0 }, 103 { ARM::t2UXTBr, ARM::tUXTB, 0, 0, 0, 1, 0, 1,0, 0 }, 104 { ARM::t2UXTHr, ARM::tUXTH, 0, 0, 0, 1, 0, 1,0, 0 }, 105 106 // FIXME: Clean this up after splitting each Thumb load / store opcode 107 // into multiple ones.
|
117 { ARM::t2STRs, ARM::tSTR, 0, 0, 0, 1, 0, 0,0, 1 }, 118 { ARM::t2STRBi12,ARM::tSTRB, 0, 5, 0, 1, 0, 0,0, 1 }, 119 { ARM::t2STRBs, ARM::tSTRB, 0, 0, 0, 1, 0, 0,0, 1 }, 120 { ARM::t2STRHi12,ARM::tSTRH, 0, 5, 0, 1, 0, 0,0, 1 }, 121 { ARM::t2STRHs, ARM::tSTRH, 0, 0, 0, 1, 0, 0,0, 1 }, 122 123 { ARM::t2LDM_RET,0, ARM::tPOP_RET, 0, 0, 1, 1, 1,1, 1 }, 124 { ARM::t2LDM, ARM::tLDM, ARM::tPOP, 0, 0, 1, 1, 1,1, 1 }, 125 { ARM::t2STM, ARM::tSTM, ARM::tPUSH, 0, 0, 1, 1, 1,1, 1 }, 126 }; 127 128 class Thumb2SizeReduce : public MachineFunctionPass { 129 public: 130 static char ID; 131 Thumb2SizeReduce(); 132 133 const Thumb2InstrInfo *TII; 134 135 virtual bool runOnMachineFunction(MachineFunction &MF); 136 137 virtual const char *getPassName() const { 138 return "Thumb2 instruction size reduction pass"; 139 } 140 141 private: 142 /// ReduceOpcodeMap - Maps wide opcode to index of entry in ReduceTable. 143 DenseMap<unsigned, unsigned> ReduceOpcodeMap; 144 145 bool VerifyPredAndCC(MachineInstr *MI, const ReduceEntry &Entry, 146 bool is2Addr, ARMCC::CondCodes Pred, 147 bool LiveCPSR, bool &HasCC, bool &CCDead); 148 149 bool ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI, 150 const ReduceEntry &Entry); 151 152 bool ReduceSpecial(MachineBasicBlock &MBB, MachineInstr *MI, 153 const ReduceEntry &Entry, bool LiveCPSR); 154 155 /// ReduceTo2Addr - Reduce a 32-bit instruction to a 16-bit two-address 156 /// instruction. 157 bool ReduceTo2Addr(MachineBasicBlock &MBB, MachineInstr *MI, 158 const ReduceEntry &Entry, 159 bool LiveCPSR); 160 161 /// ReduceToNarrow - Reduce a 32-bit instruction to a 16-bit 162 /// non-two-address instruction. 163 bool ReduceToNarrow(MachineBasicBlock &MBB, MachineInstr *MI, 164 const ReduceEntry &Entry, 165 bool LiveCPSR); 166 167 /// ReduceMBB - Reduce width of instructions in the specified basic block. 168 bool ReduceMBB(MachineBasicBlock &MBB); 169 }; 170 char Thumb2SizeReduce::ID = 0; 171} 172 173Thumb2SizeReduce::Thumb2SizeReduce() : MachineFunctionPass(&ID) { 174 for (unsigned i = 0, e = array_lengthof(ReduceTable); i != e; ++i) { 175 unsigned FromOpc = ReduceTable[i].WideOpc; 176 if (!ReduceOpcodeMap.insert(std::make_pair(FromOpc, i)).second) 177 assert(false && "Duplicated entries?"); 178 } 179} 180 181static bool HasImplicitCPSRDef(const TargetInstrDesc &TID) { 182 for (const unsigned *Regs = TID.ImplicitDefs; *Regs; ++Regs) 183 if (*Regs == ARM::CPSR) 184 return true; 185 return false; 186} 187 188bool 189Thumb2SizeReduce::VerifyPredAndCC(MachineInstr *MI, const ReduceEntry &Entry, 190 bool is2Addr, ARMCC::CondCodes Pred, 191 bool LiveCPSR, bool &HasCC, bool &CCDead) { 192 if ((is2Addr && Entry.PredCC2 == 0) || 193 (!is2Addr && Entry.PredCC1 == 0)) { 194 if (Pred == ARMCC::AL) { 195 // Not predicated, must set CPSR. 196 if (!HasCC) { 197 // Original instruction was not setting CPSR, but CPSR is not 198 // currently live anyway. It's ok to set it. The CPSR def is 199 // dead though. 200 if (!LiveCPSR) { 201 HasCC = true; 202 CCDead = true; 203 return true; 204 } 205 return false; 206 } 207 } else { 208 // Predicated, must not set CPSR. 209 if (HasCC) 210 return false; 211 } 212 } else if ((is2Addr && Entry.PredCC2 == 2) || 213 (!is2Addr && Entry.PredCC1 == 2)) { 214 /// Old opcode has an optional def of CPSR. 215 if (HasCC) 216 return true; 217 // If both old opcode does not implicit CPSR def, then it's not ok since 218 // these new opcodes CPSR def is not meant to be thrown away. e.g. CMP. 219 if (!HasImplicitCPSRDef(MI->getDesc())) 220 return false; 221 HasCC = true; 222 } else { 223 // 16-bit instruction does not set CPSR. 224 if (HasCC) 225 return false; 226 } 227 228 return true; 229} 230 231static bool VerifyLowRegs(MachineInstr *MI) { 232 unsigned Opc = MI->getOpcode(); 233 bool isPCOk = (Opc == ARM::t2LDM_RET) || (Opc == ARM::t2LDM); 234 bool isLROk = (Opc == ARM::t2STM); 235 bool isSPOk = isPCOk || isLROk || (Opc == ARM::t2ADDrSPi); 236 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 237 const MachineOperand &MO = MI->getOperand(i); 238 if (!MO.isReg() || MO.isImplicit()) 239 continue; 240 unsigned Reg = MO.getReg(); 241 if (Reg == 0 || Reg == ARM::CPSR) 242 continue; 243 if (isPCOk && Reg == ARM::PC) 244 continue; 245 if (isLROk && Reg == ARM::LR) 246 continue;
| 117 { ARM::t2STRs, ARM::tSTR, 0, 0, 0, 1, 0, 0,0, 1 }, 118 { ARM::t2STRBi12,ARM::tSTRB, 0, 5, 0, 1, 0, 0,0, 1 }, 119 { ARM::t2STRBs, ARM::tSTRB, 0, 0, 0, 1, 0, 0,0, 1 }, 120 { ARM::t2STRHi12,ARM::tSTRH, 0, 5, 0, 1, 0, 0,0, 1 }, 121 { ARM::t2STRHs, ARM::tSTRH, 0, 0, 0, 1, 0, 0,0, 1 }, 122 123 { ARM::t2LDM_RET,0, ARM::tPOP_RET, 0, 0, 1, 1, 1,1, 1 }, 124 { ARM::t2LDM, ARM::tLDM, ARM::tPOP, 0, 0, 1, 1, 1,1, 1 }, 125 { ARM::t2STM, ARM::tSTM, ARM::tPUSH, 0, 0, 1, 1, 1,1, 1 }, 126 }; 127 128 class Thumb2SizeReduce : public MachineFunctionPass { 129 public: 130 static char ID; 131 Thumb2SizeReduce(); 132 133 const Thumb2InstrInfo *TII; 134 135 virtual bool runOnMachineFunction(MachineFunction &MF); 136 137 virtual const char *getPassName() const { 138 return "Thumb2 instruction size reduction pass"; 139 } 140 141 private: 142 /// ReduceOpcodeMap - Maps wide opcode to index of entry in ReduceTable. 143 DenseMap<unsigned, unsigned> ReduceOpcodeMap; 144 145 bool VerifyPredAndCC(MachineInstr *MI, const ReduceEntry &Entry, 146 bool is2Addr, ARMCC::CondCodes Pred, 147 bool LiveCPSR, bool &HasCC, bool &CCDead); 148 149 bool ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI, 150 const ReduceEntry &Entry); 151 152 bool ReduceSpecial(MachineBasicBlock &MBB, MachineInstr *MI, 153 const ReduceEntry &Entry, bool LiveCPSR); 154 155 /// ReduceTo2Addr - Reduce a 32-bit instruction to a 16-bit two-address 156 /// instruction. 157 bool ReduceTo2Addr(MachineBasicBlock &MBB, MachineInstr *MI, 158 const ReduceEntry &Entry, 159 bool LiveCPSR); 160 161 /// ReduceToNarrow - Reduce a 32-bit instruction to a 16-bit 162 /// non-two-address instruction. 163 bool ReduceToNarrow(MachineBasicBlock &MBB, MachineInstr *MI, 164 const ReduceEntry &Entry, 165 bool LiveCPSR); 166 167 /// ReduceMBB - Reduce width of instructions in the specified basic block. 168 bool ReduceMBB(MachineBasicBlock &MBB); 169 }; 170 char Thumb2SizeReduce::ID = 0; 171} 172 173Thumb2SizeReduce::Thumb2SizeReduce() : MachineFunctionPass(&ID) { 174 for (unsigned i = 0, e = array_lengthof(ReduceTable); i != e; ++i) { 175 unsigned FromOpc = ReduceTable[i].WideOpc; 176 if (!ReduceOpcodeMap.insert(std::make_pair(FromOpc, i)).second) 177 assert(false && "Duplicated entries?"); 178 } 179} 180 181static bool HasImplicitCPSRDef(const TargetInstrDesc &TID) { 182 for (const unsigned *Regs = TID.ImplicitDefs; *Regs; ++Regs) 183 if (*Regs == ARM::CPSR) 184 return true; 185 return false; 186} 187 188bool 189Thumb2SizeReduce::VerifyPredAndCC(MachineInstr *MI, const ReduceEntry &Entry, 190 bool is2Addr, ARMCC::CondCodes Pred, 191 bool LiveCPSR, bool &HasCC, bool &CCDead) { 192 if ((is2Addr && Entry.PredCC2 == 0) || 193 (!is2Addr && Entry.PredCC1 == 0)) { 194 if (Pred == ARMCC::AL) { 195 // Not predicated, must set CPSR. 196 if (!HasCC) { 197 // Original instruction was not setting CPSR, but CPSR is not 198 // currently live anyway. It's ok to set it. The CPSR def is 199 // dead though. 200 if (!LiveCPSR) { 201 HasCC = true; 202 CCDead = true; 203 return true; 204 } 205 return false; 206 } 207 } else { 208 // Predicated, must not set CPSR. 209 if (HasCC) 210 return false; 211 } 212 } else if ((is2Addr && Entry.PredCC2 == 2) || 213 (!is2Addr && Entry.PredCC1 == 2)) { 214 /// Old opcode has an optional def of CPSR. 215 if (HasCC) 216 return true; 217 // If both old opcode does not implicit CPSR def, then it's not ok since 218 // these new opcodes CPSR def is not meant to be thrown away. e.g. CMP. 219 if (!HasImplicitCPSRDef(MI->getDesc())) 220 return false; 221 HasCC = true; 222 } else { 223 // 16-bit instruction does not set CPSR. 224 if (HasCC) 225 return false; 226 } 227 228 return true; 229} 230 231static bool VerifyLowRegs(MachineInstr *MI) { 232 unsigned Opc = MI->getOpcode(); 233 bool isPCOk = (Opc == ARM::t2LDM_RET) || (Opc == ARM::t2LDM); 234 bool isLROk = (Opc == ARM::t2STM); 235 bool isSPOk = isPCOk || isLROk || (Opc == ARM::t2ADDrSPi); 236 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 237 const MachineOperand &MO = MI->getOperand(i); 238 if (!MO.isReg() || MO.isImplicit()) 239 continue; 240 unsigned Reg = MO.getReg(); 241 if (Reg == 0 || Reg == ARM::CPSR) 242 continue; 243 if (isPCOk && Reg == ARM::PC) 244 continue; 245 if (isLROk && Reg == ARM::LR) 246 continue;
|