1 //===-- AlphaLLRP.cpp - Alpha Load Load Replay Trap elimination pass. -- --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Here we check for potential replay traps introduced by the spiller
11 // We also align some branch targets if we can do so for free.
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "alpha-nops"
17 #include "llvm/CodeGen/MachineFunctionPass.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/Target/TargetMachine.h"
20 #include "llvm/Target/TargetInstrInfo.h"
21 #include "llvm/ADT/SetOperations.h"
22 #include "llvm/ADT/Statistic.h"
23 #include "llvm/Support/CommandLine.h"
26 STATISTIC(nopintro, "Number of nops inserted");
27 STATISTIC(nopalign, "Number of nops inserted for alignment");
31 AlignAll("alpha-align-all", cl::Hidden,
32 cl::desc("Align all blocks"));
34 struct AlphaLLRPPass : public MachineFunctionPass {
35 /// Target machine description which we query for reg. names, data
38 AlphaTargetMachine &TM;
41 AlphaLLRPPass(AlphaTargetMachine &tm)
42 : MachineFunctionPass((intptr_t)&ID), TM(tm) { }
44 virtual const char *getPassName() const {
45 return "Alpha NOP inserter";
48 bool runOnMachineFunction(MachineFunction &F) {
49 const TargetInstrInfo *TII = F.getTarget().getInstrInfo();
51 MachineInstr* prev[3] = {0,0,0};
53 for (MachineFunction::iterator FI = F.begin(), FE = F.end();
55 MachineBasicBlock& MBB = *FI;
57 for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) {
59 prev[0] = prev[1] = prev[2] = 0; //Slots cleared at fetch boundary
61 MachineInstr *MI = I++;
62 switch (MI->getOpcode()) {
63 case Alpha::LDQ: case Alpha::LDL:
64 case Alpha::LDWU: case Alpha::LDBU:
65 case Alpha::LDT: case Alpha::LDS:
66 case Alpha::STQ: case Alpha::STL:
67 case Alpha::STW: case Alpha::STB:
68 case Alpha::STT: case Alpha::STS:
69 if (MI->getOperand(2).getReg() == Alpha::R30) {
71 && prev[0]->getOperand(2).getReg() ==
72 MI->getOperand(2).getReg()
73 && prev[0]->getOperand(1).getImmedValue() ==
74 MI->getOperand(1).getImmedValue()) {
78 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31)
81 Changed = true; nopintro += 1;
84 && prev[1]->getOperand(2).getReg() ==
85 MI->getOperand(2).getReg()
86 && prev[1]->getOperand(1).getImmedValue() ==
87 MI->getOperand(1).getImmedValue()) {
89 prev[1] = prev[2] = 0;
90 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31)
93 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31)
96 Changed = true; nopintro += 2;
99 && prev[2]->getOperand(2).getReg() ==
100 MI->getOperand(2).getReg()
101 && prev[2]->getOperand(1).getImmedValue() ==
102 MI->getOperand(1).getImmedValue()) {
103 prev[0] = prev[1] = prev[2] = 0;
104 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31).addReg(Alpha::R31)
106 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31).addReg(Alpha::R31)
108 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31).addReg(Alpha::R31)
110 Changed = true; nopintro += 3;
123 case Alpha::MEMLABEL:
126 case Alpha::IDEF_F32:
127 case Alpha::IDEF_F64:
141 if (ub || AlignAll) {
142 //we can align stuff for free at this point
144 BuildMI(MBB, MBB.end(), TII->get(Alpha::BISr), Alpha::R31)
145 .addReg(Alpha::R31).addReg(Alpha::R31);
157 char AlphaLLRPPass::ID = 0;
158 } // end of anonymous namespace
160 FunctionPass *llvm::createAlphaLLRPPass(AlphaTargetMachine &tm) {
161 return new AlphaLLRPPass(tm);