LLVM: lib/Target/ARC/ARCBranchFinalize.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
23#include
24
25#define DEBUG_TYPE "arc-branch-finalize"
26
27using namespace llvm;
28
29namespace llvm {
30
33
34}
35
36namespace {
37
39public:
40 static char ID;
41
44 }
45
46 StringRef getPassName() const override {
47 return "ARC Branch Finalization Pass";
48 }
49
50 bool runOnMachineFunction(MachineFunction &MF) override;
51 void replaceWithBRcc(MachineInstr *MI) const;
52 void replaceWithCmpBcc(MachineInstr *MI) const;
53
54private:
55 const ARCInstrInfo *TII{nullptr};
56};
57
58char ARCBranchFinalize::ID = 0;
59
60}
61
63 "ARC finalize branches", false, false)
67
68
69
70
71
72
73
74
75
77 switch (CC) {
79 return 0;
81 return 1;
83 return 2;
85 return 3;
87 return 4;
89 return 5;
90 default:
91 return -1U;
92 }
93}
94
96 return !(MI->getOpcode() != ARC::BRcc_rr_p &&
97 MI->getOpcode() != ARC::BRcc_ru6_p);
98}
99
102 if (MI->getOpcode() == ARC::BRcc_rr_p)
103 return ARC::BRcc_rr;
104 return ARC::BRcc_ru6;
105}
106
109 if (MI->getOpcode() == ARC::BRcc_rr_p)
110 return ARC::CMP_rr;
111 return ARC::CMP_ru6;
112}
113
114void ARCBranchFinalize::replaceWithBRcc(MachineInstr *MI) const {
115 LLVM_DEBUG(dbgs() << "Replacing pseudo branch with BRcc\n");
116 unsigned CC = getCCForBRcc(MI->getOperand(3).getImm());
117 if (CC != -1U) {
120 .addMBB(MI->getOperand(0).getMBB())
121 .addReg(MI->getOperand(1).getReg())
124 MI->eraseFromParent();
125 } else {
126 replaceWithCmpBcc(MI);
127 }
128}
129
130void ARCBranchFinalize::replaceWithCmpBcc(MachineInstr *MI) const {
132 LLVM_DEBUG(dbgs() << "Replacing pseudo branch with Cmp + Bcc\n");
135 .addReg(MI->getOperand(1).getReg())
137 BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), TII->get(ARC::Bcc))
138 .addMBB(MI->getOperand(0).getMBB())
139 .addImm(MI->getOperand(3).getImm());
140 MI->eraseFromParent();
141}
142
143bool ARCBranchFinalize::runOnMachineFunction(MachineFunction &MF) {
145 << "\n");
146 std::vector<MachineInstr *> Branches;
148 unsigned MaxSize = 0;
150 std::map<MachineBasicBlock *, unsigned> BlockToPCMap;
151 std::vector<std::pair<MachineInstr *, unsigned>> BranchToPCList;
152 unsigned PC = 0;
153
154 for (auto &MBB : MF) {
155 BlockToPCMap.insert(std::make_pair(&MBB, PC));
157 unsigned Size = TII->getInstSizeInBytes(MI);
159 LLVM_DEBUG(dbgs() << "Unknown (or size 0) size for: " << MI << "\n");
160 } else {
161 MaxSize += Size;
162 }
163 if (MI.isBranch()) {
164 Branches.push_back(&MI);
165 BranchToPCList.emplace_back(&MI, PC);
166 }
168 }
169 }
170 for (auto P : BranchToPCList) {
172 isInt<9>(MaxSize) ? replaceWithBRcc(P.first) : replaceWithCmpBcc(P.first);
173 }
174
175 LLVM_DEBUG(dbgs() << "Estimated function size for " << MF.getName() << ": "
176 << MaxSize << "\n");
177
179}
180
182 return new ARCBranchFinalize();
183}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static unsigned getCmpForPseudo(MachineInstr *MI)
Definition ARCBranchFinalize.cpp:107
static unsigned getBRccForPseudo(MachineInstr *MI)
Definition ARCBranchFinalize.cpp:100
static bool isBRccPseudo(MachineInstr *MI)
Definition ARCBranchFinalize.cpp:95
arc branch ARC finalize static false unsigned getCCForBRcc(unsigned CC)
Definition ARCBranchFinalize.cpp:76
const HexagonInstrInfo * TII
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
FunctionPass class - This class is used to implement most global optimizations.
Analysis pass which computes a MachineDominatorTree.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A global registry used in conjunction with static constructors to make pluggable components (like tar...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void initializeARCBranchFinalizePass(PassRegistry &Registry)
FunctionPass * createARCBranchFinalizePass()
Definition ARCBranchFinalize.cpp:181