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};
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
);