1 //===-- AlphaLLRP.cpp - Alpha Load Load Replay Trap elimination pass. -- --===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by Andrew Lenharth and is distributed under the
6 // University of Illinois Open Source 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;
40 AlphaLLRPPass(AlphaTargetMachine &tm) : TM(tm) { }
42 virtual const char *getPassName() const {
43 return "Alpha NOP inserter";
46 bool runOnMachineFunction(MachineFunction &F) {
47 const TargetInstrInfo *TII = F.getTarget().getInstrInfo();
49 MachineInstr* prev[3] = {0,0,0};
51 for (MachineFunction::iterator FI = F.begin(), FE = F.end();
53 MachineBasicBlock& MBB = *FI;
55 for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) {
57 prev[0] = prev[1] = prev[2] = 0; //Slots cleared at fetch boundary
59 MachineInstr *MI = I++;
60 switch (MI->getOpcode()) {
61 case Alpha::LDQ: case Alpha::LDL:
62 case Alpha::LDWU: case Alpha::LDBU:
63 case Alpha::LDT: case Alpha::LDS:
64 case Alpha::STQ: case Alpha::STL:
65 case Alpha::STW: case Alpha::STB:
66 case Alpha::STT: case Alpha::STS:
67 if (MI->getOperand(2).getReg() == Alpha::R30) {
69 && prev[0]->getOperand(2).getReg() ==
70 MI->getOperand(2).getReg()
71 && prev[0]->getOperand(1).getImmedValue() ==
72 MI->getOperand(1).getImmedValue()) {
76 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31).addReg(Alpha::R31)
78 Changed = true; nopintro += 1;
81 && prev[1]->getOperand(2).getReg() ==
82 MI->getOperand(2).getReg()
83 && prev[1]->getOperand(1).getImmedValue() ==
84 MI->getOperand(1).getImmedValue()) {
86 prev[1] = prev[2] = 0;
87 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31).addReg(Alpha::R31)
89 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31).addReg(Alpha::R31)
91 Changed = true; nopintro += 2;
94 && prev[2]->getOperand(2).getReg() ==
95 MI->getOperand(2).getReg()
96 && prev[2]->getOperand(1).getImmedValue() ==
97 MI->getOperand(1).getImmedValue()) {
98 prev[0] = prev[1] = prev[2] = 0;
99 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31).addReg(Alpha::R31)
101 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31).addReg(Alpha::R31)
103 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31).addReg(Alpha::R31)
105 Changed = true; nopintro += 3;
118 case Alpha::MEMLABEL:
121 case Alpha::IDEF_F32:
122 case Alpha::IDEF_F64:
136 if (ub || AlignAll) {
137 //we can align stuff for free at this point
139 BuildMI(MBB, MBB.end(), TII->get(Alpha::BISr), Alpha::R31)
140 .addReg(Alpha::R31).addReg(Alpha::R31);
152 } // end of anonymous namespace
154 FunctionPass *llvm::createAlphaLLRPPass(AlphaTargetMachine &tm) {
155 return new AlphaLLRPPass(tm);