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(&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};
52 DebugLoc dl = DebugLoc::getUnknownLoc();
54 for (MachineFunction::iterator FI = F.begin(), FE = F.end();
56 MachineBasicBlock& MBB = *FI;
58 for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) {
60 prev[0] = prev[1] = prev[2] = 0; //Slots cleared at fetch boundary
62 MachineInstr *MI = I++;
63 switch (MI->getOpcode()) {
64 case Alpha::LDQ: case Alpha::LDL:
65 case Alpha::LDWU: case Alpha::LDBU:
66 case Alpha::LDT: case Alpha::LDS:
67 case Alpha::STQ: case Alpha::STL:
68 case Alpha::STW: case Alpha::STB:
69 case Alpha::STT: case Alpha::STS:
70 if (MI->getOperand(2).getReg() == Alpha::R30) {
72 prev[0]->getOperand(2).getReg() == MI->getOperand(2).getReg()&&
73 prev[0]->getOperand(1).getImm() == MI->getOperand(1).getImm()){
77 BuildMI(MBB, MI, dl, TII->get(Alpha::BISr), Alpha::R31)
80 Changed = true; nopintro += 1;
83 && prev[1]->getOperand(2).getReg() ==
84 MI->getOperand(2).getReg()
85 && prev[1]->getOperand(1).getImm() ==
86 MI->getOperand(1).getImm()) {
88 prev[1] = prev[2] = 0;
89 BuildMI(MBB, MI, dl, TII->get(Alpha::BISr), Alpha::R31)
92 BuildMI(MBB, MI, dl, TII->get(Alpha::BISr), Alpha::R31)
95 Changed = true; nopintro += 2;
98 && prev[2]->getOperand(2).getReg() ==
99 MI->getOperand(2).getReg()
100 && prev[2]->getOperand(1).getImm() ==
101 MI->getOperand(1).getImm()) {
102 prev[0] = prev[1] = prev[2] = 0;
103 BuildMI(MBB, MI, dl, TII->get(Alpha::BISr), Alpha::R31)
104 .addReg(Alpha::R31).addReg(Alpha::R31);
105 BuildMI(MBB, MI, dl, TII->get(Alpha::BISr), Alpha::R31)
106 .addReg(Alpha::R31).addReg(Alpha::R31);
107 BuildMI(MBB, MI, dl, TII->get(Alpha::BISr), Alpha::R31)
108 .addReg(Alpha::R31).addReg(Alpha::R31);
109 Changed = true; nopintro += 3;
122 case Alpha::MEMLABEL:
137 if (ub || AlignAll) {
138 //we can align stuff for free at this point
140 BuildMI(MBB, MBB.end(), dl, TII->get(Alpha::BISr), Alpha::R31)
141 .addReg(Alpha::R31).addReg(Alpha::R31);
153 char AlphaLLRPPass::ID = 0;
154 } // end of anonymous namespace
156 FunctionPass *llvm::createAlphaLLRPPass(AlphaTargetMachine &tm) {
157 return new AlphaLLRPPass(tm);