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() == MI->getOperand(2).getReg()&&
72 prev[0]->getOperand(1).getImm() == MI->getOperand(1).getImm()){
76 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31)
79 Changed = true; nopintro += 1;
82 && prev[1]->getOperand(2).getReg() ==
83 MI->getOperand(2).getReg()
84 && prev[1]->getOperand(1).getImm() ==
85 MI->getOperand(1).getImm()) {
87 prev[1] = prev[2] = 0;
88 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31)
91 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31)
94 Changed = true; nopintro += 2;
97 && prev[2]->getOperand(2).getReg() ==
98 MI->getOperand(2).getReg()
99 && prev[2]->getOperand(1).getImm() ==
100 MI->getOperand(1).getImm()) {
101 prev[0] = prev[1] = prev[2] = 0;
102 BuildMI(MBB, MI, TII->get(Alpha::BISr), Alpha::R31).addReg(Alpha::R31)
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 Changed = true; nopintro += 3;
121 case Alpha::MEMLABEL:
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 char AlphaLLRPPass::ID = 0;
153 } // end of anonymous namespace
155 FunctionPass *llvm::createAlphaLLRPPass(AlphaTargetMachine &tm) {
156 return new AlphaLLRPPass(tm);