Mercurial > hg > CbC > CbC_llvm
comparison lib/CodeGen/ShrinkWrap.cpp @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | 1172e4bd9c6f |
children | 3a76565eade5 |
comparison
equal
deleted
inserted
replaced
120:1172e4bd9c6f | 121:803732b1fca8 |
---|---|
1 //===-- ShrinkWrap.cpp - Compute safe point for prolog/epilog insertion ---===// | 1 //===- ShrinkWrap.cpp - Compute safe point for prolog/epilog insertion ----===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
43 // points must be in the same loop. | 43 // points must be in the same loop. |
44 // Property #3 is ensured via the MachineBlockFrequencyInfo. | 44 // Property #3 is ensured via the MachineBlockFrequencyInfo. |
45 // | 45 // |
46 // If this pass found points matching all these properties, then | 46 // If this pass found points matching all these properties, then |
47 // MachineFrameInfo is updated with this information. | 47 // MachineFrameInfo is updated with this information. |
48 // | |
48 //===----------------------------------------------------------------------===// | 49 //===----------------------------------------------------------------------===// |
50 | |
49 #include "llvm/ADT/BitVector.h" | 51 #include "llvm/ADT/BitVector.h" |
50 #include "llvm/ADT/PostOrderIterator.h" | 52 #include "llvm/ADT/PostOrderIterator.h" |
51 #include "llvm/ADT/SetVector.h" | 53 #include "llvm/ADT/SetVector.h" |
54 #include "llvm/ADT/SmallVector.h" | |
52 #include "llvm/ADT/Statistic.h" | 55 #include "llvm/ADT/Statistic.h" |
53 // To check for profitability. | 56 #include "llvm/CodeGen/MachineBasicBlock.h" |
54 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" | 57 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" |
55 // For property #1 for Save. | |
56 #include "llvm/CodeGen/MachineDominators.h" | 58 #include "llvm/CodeGen/MachineDominators.h" |
59 #include "llvm/CodeGen/MachineFunction.h" | |
57 #include "llvm/CodeGen/MachineFunctionPass.h" | 60 #include "llvm/CodeGen/MachineFunctionPass.h" |
58 // To record the result of the analysis. | |
59 #include "llvm/CodeGen/MachineFrameInfo.h" | 61 #include "llvm/CodeGen/MachineFrameInfo.h" |
60 // For property #2. | 62 #include "llvm/CodeGen/MachineInstr.h" |
61 #include "llvm/CodeGen/MachineLoopInfo.h" | 63 #include "llvm/CodeGen/MachineLoopInfo.h" |
62 // For property #1 for Restore. | 64 #include "llvm/CodeGen/MachineOperand.h" |
63 #include "llvm/CodeGen/MachinePostDominators.h" | 65 #include "llvm/CodeGen/MachinePostDominators.h" |
64 #include "llvm/CodeGen/Passes.h" | |
65 // To know about callee-saved. | |
66 #include "llvm/CodeGen/RegisterClassInfo.h" | 66 #include "llvm/CodeGen/RegisterClassInfo.h" |
67 #include "llvm/CodeGen/RegisterScavenging.h" | 67 #include "llvm/CodeGen/RegisterScavenging.h" |
68 #include "llvm/IR/Attributes.h" | |
69 #include "llvm/IR/Function.h" | |
68 #include "llvm/MC/MCAsmInfo.h" | 70 #include "llvm/MC/MCAsmInfo.h" |
71 #include "llvm/Pass.h" | |
72 #include "llvm/Support/CommandLine.h" | |
69 #include "llvm/Support/Debug.h" | 73 #include "llvm/Support/Debug.h" |
70 // To query the target about frame lowering. | 74 #include "llvm/Support/ErrorHandling.h" |
75 #include "llvm/Support/raw_ostream.h" | |
71 #include "llvm/Target/TargetFrameLowering.h" | 76 #include "llvm/Target/TargetFrameLowering.h" |
72 // To know about frame setup operation. | |
73 #include "llvm/Target/TargetInstrInfo.h" | 77 #include "llvm/Target/TargetInstrInfo.h" |
74 #include "llvm/Target/TargetMachine.h" | 78 #include "llvm/Target/TargetMachine.h" |
75 // To access TargetInstrInfo. | 79 #include "llvm/Target/TargetRegisterInfo.h" |
76 #include "llvm/Target/TargetSubtargetInfo.h" | 80 #include "llvm/Target/TargetSubtargetInfo.h" |
81 #include <cassert> | |
82 #include <cstdint> | |
83 #include <memory> | |
84 | |
85 using namespace llvm; | |
77 | 86 |
78 #define DEBUG_TYPE "shrink-wrap" | 87 #define DEBUG_TYPE "shrink-wrap" |
79 | |
80 using namespace llvm; | |
81 | 88 |
82 STATISTIC(NumFunc, "Number of functions"); | 89 STATISTIC(NumFunc, "Number of functions"); |
83 STATISTIC(NumCandidates, "Number of shrink-wrapping candidates"); | 90 STATISTIC(NumCandidates, "Number of shrink-wrapping candidates"); |
84 STATISTIC(NumCandidatesDropped, | 91 STATISTIC(NumCandidatesDropped, |
85 "Number of shrink-wrapping candidates dropped because of frequency"); | 92 "Number of shrink-wrapping candidates dropped because of frequency"); |
86 | 93 |
87 static cl::opt<cl::boolOrDefault> | 94 static cl::opt<cl::boolOrDefault> |
88 EnableShrinkWrapOpt("enable-shrink-wrap", cl::Hidden, | 95 EnableShrinkWrapOpt("enable-shrink-wrap", cl::Hidden, |
89 cl::desc("enable the shrink-wrapping pass")); | 96 cl::desc("enable the shrink-wrapping pass")); |
90 | 97 |
91 namespace { | 98 namespace { |
99 | |
92 /// \brief Class to determine where the safe point to insert the | 100 /// \brief Class to determine where the safe point to insert the |
93 /// prologue and epilogue are. | 101 /// prologue and epilogue are. |
94 /// Unlike the paper from Fred C. Chow, PLDI'88, that introduces the | 102 /// Unlike the paper from Fred C. Chow, PLDI'88, that introduces the |
95 /// shrink-wrapping term for prologue/epilogue placement, this pass | 103 /// shrink-wrapping term for prologue/epilogue placement, this pass |
96 /// does not rely on expensive data-flow analysis. Instead we use the | 104 /// does not rely on expensive data-flow analysis. Instead we use the |
99 class ShrinkWrap : public MachineFunctionPass { | 107 class ShrinkWrap : public MachineFunctionPass { |
100 /// Hold callee-saved information. | 108 /// Hold callee-saved information. |
101 RegisterClassInfo RCI; | 109 RegisterClassInfo RCI; |
102 MachineDominatorTree *MDT; | 110 MachineDominatorTree *MDT; |
103 MachinePostDominatorTree *MPDT; | 111 MachinePostDominatorTree *MPDT; |
112 | |
104 /// Current safe point found for the prologue. | 113 /// Current safe point found for the prologue. |
105 /// The prologue will be inserted before the first instruction | 114 /// The prologue will be inserted before the first instruction |
106 /// in this basic block. | 115 /// in this basic block. |
107 MachineBasicBlock *Save; | 116 MachineBasicBlock *Save; |
117 | |
108 /// Current safe point found for the epilogue. | 118 /// Current safe point found for the epilogue. |
109 /// The epilogue will be inserted before the first terminator instruction | 119 /// The epilogue will be inserted before the first terminator instruction |
110 /// in this basic block. | 120 /// in this basic block. |
111 MachineBasicBlock *Restore; | 121 MachineBasicBlock *Restore; |
122 | |
112 /// Hold the information of the basic block frequency. | 123 /// Hold the information of the basic block frequency. |
113 /// Use to check the profitability of the new points. | 124 /// Use to check the profitability of the new points. |
114 MachineBlockFrequencyInfo *MBFI; | 125 MachineBlockFrequencyInfo *MBFI; |
126 | |
115 /// Hold the loop information. Used to determine if Save and Restore | 127 /// Hold the loop information. Used to determine if Save and Restore |
116 /// are in the same loop. | 128 /// are in the same loop. |
117 MachineLoopInfo *MLI; | 129 MachineLoopInfo *MLI; |
130 | |
118 /// Frequency of the Entry block. | 131 /// Frequency of the Entry block. |
119 uint64_t EntryFreq; | 132 uint64_t EntryFreq; |
133 | |
120 /// Current opcode for frame setup. | 134 /// Current opcode for frame setup. |
121 unsigned FrameSetupOpcode; | 135 unsigned FrameSetupOpcode; |
136 | |
122 /// Current opcode for frame destroy. | 137 /// Current opcode for frame destroy. |
123 unsigned FrameDestroyOpcode; | 138 unsigned FrameDestroyOpcode; |
139 | |
124 /// Entry block. | 140 /// Entry block. |
125 const MachineBasicBlock *Entry; | 141 const MachineBasicBlock *Entry; |
126 typedef SmallSetVector<unsigned, 16> SetOfRegs; | 142 |
143 using SetOfRegs = SmallSetVector<unsigned, 16>; | |
144 | |
127 /// Registers that need to be saved for the current function. | 145 /// Registers that need to be saved for the current function. |
128 mutable SetOfRegs CurrentCSRs; | 146 mutable SetOfRegs CurrentCSRs; |
147 | |
129 /// Current MachineFunction. | 148 /// Current MachineFunction. |
130 MachineFunction *MachineFunc; | 149 MachineFunction *MachineFunc; |
131 | 150 |
132 /// \brief Check if \p MI uses or defines a callee-saved register or | 151 /// \brief Check if \p MI uses or defines a callee-saved register or |
133 /// a frame index. If this is the case, this means \p MI must happen | 152 /// a frame index. If this is the case, this means \p MI must happen |
203 | 222 |
204 /// \brief Perform the shrink-wrapping analysis and update | 223 /// \brief Perform the shrink-wrapping analysis and update |
205 /// the MachineFrameInfo attached to \p MF with the results. | 224 /// the MachineFrameInfo attached to \p MF with the results. |
206 bool runOnMachineFunction(MachineFunction &MF) override; | 225 bool runOnMachineFunction(MachineFunction &MF) override; |
207 }; | 226 }; |
208 } // End anonymous namespace. | 227 |
228 } // end anonymous namespace | |
209 | 229 |
210 char ShrinkWrap::ID = 0; | 230 char ShrinkWrap::ID = 0; |
231 | |
211 char &llvm::ShrinkWrapID = ShrinkWrap::ID; | 232 char &llvm::ShrinkWrapID = ShrinkWrap::ID; |
212 | 233 |
213 INITIALIZE_PASS_BEGIN(ShrinkWrap, "shrink-wrap", "Shrink Wrap Pass", false, | 234 INITIALIZE_PASS_BEGIN(ShrinkWrap, DEBUG_TYPE, "Shrink Wrap Pass", false, false) |
214 false) | |
215 INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo) | 235 INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo) |
216 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) | 236 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) |
217 INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree) | 237 INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree) |
218 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) | 238 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) |
219 INITIALIZE_PASS_END(ShrinkWrap, "shrink-wrap", "Shrink Wrap Pass", false, false) | 239 INITIALIZE_PASS_END(ShrinkWrap, DEBUG_TYPE, "Shrink Wrap Pass", false, false) |
220 | 240 |
221 bool ShrinkWrap::useOrDefCSROrFI(const MachineInstr &MI, | 241 bool ShrinkWrap::useOrDefCSROrFI(const MachineInstr &MI, |
222 RegScavenger *RS) const { | 242 RegScavenger *RS) const { |
223 if (MI.getOpcode() == FrameSetupOpcode || | 243 if (MI.getOpcode() == FrameSetupOpcode || |
224 MI.getOpcode() == FrameDestroyOpcode) { | 244 MI.getOpcode() == FrameDestroyOpcode) { |
280 return; | 300 return; |
281 } | 301 } |
282 | 302 |
283 if (!Restore) | 303 if (!Restore) |
284 Restore = &MBB; | 304 Restore = &MBB; |
305 else if (MPDT->getNode(&MBB)) // If the block is not in the post dom tree, it | |
306 // means the block never returns. If that's the | |
307 // case, we don't want to call | |
308 // `findNearestCommonDominator`, which will | |
309 // return `Restore`. | |
310 Restore = MPDT->findNearestCommonDominator(Restore, &MBB); | |
285 else | 311 else |
286 Restore = MPDT->findNearestCommonDominator(Restore, &MBB); | 312 Restore = nullptr; // Abort, we can't find a restore point in this case. |
287 | 313 |
288 // Make sure we would be able to insert the restore code before the | 314 // Make sure we would be able to insert the restore code before the |
289 // terminator. | 315 // terminator. |
290 if (Restore == &MBB) { | 316 if (Restore == &MBB) { |
291 for (const MachineInstr &Terminator : MBB.terminators()) { | 317 for (const MachineInstr &Terminator : MBB.terminators()) { |
292 if (!useOrDefCSROrFI(Terminator, RS)) | 318 if (!useOrDefCSROrFI(Terminator, RS)) |
293 continue; | 319 continue; |
294 // One of the terminator needs to happen before the restore point. | 320 // One of the terminator needs to happen before the restore point. |
295 if (MBB.succ_empty()) { | 321 if (MBB.succ_empty()) { |
296 Restore = nullptr; | 322 Restore = nullptr; // Abort, we can't find a restore point in this case. |
297 break; | 323 break; |
298 } | 324 } |
299 // Look for a restore point that post-dominates all the successors. | 325 // Look for a restore point that post-dominates all the successors. |
300 // The immediate post-dominator is what we are looking for. | 326 // The immediate post-dominator is what we are looking for. |
301 Restore = FindIDom<>(*Restore, Restore->successors(), *MPDT); | 327 Restore = FindIDom<>(*Restore, Restore->successors(), *MPDT); |
417 } | 443 } |
418 return false; | 444 return false; |
419 } | 445 } |
420 | 446 |
421 bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) { | 447 bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) { |
422 if (MF.empty() || !isShrinkWrapEnabled(MF)) | 448 if (skipFunction(*MF.getFunction()) || MF.empty() || !isShrinkWrapEnabled(MF)) |
423 return false; | 449 return false; |
424 | 450 |
425 DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n'); | 451 DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n'); |
426 | 452 |
427 init(MF); | 453 init(MF); |