1 //===-- SafeStackColoring.cpp - SafeStack frame coloring -------*- C++ -*--===//
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 #include "SafeStackColoring.h"
12 #include "llvm/ADT/DepthFirstIterator.h"
13 #include "llvm/IR/CFG.h"
14 #include "llvm/IR/Instructions.h"
15 #include "llvm/IR/IntrinsicInst.h"
16 #include "llvm/Support/Debug.h"
19 using namespace llvm::safestack;
21 #define DEBUG_TYPE "safestackcoloring"
23 // Disabled by default due to PR32143.
24 static cl::opt<bool> ClColoring("safe-stack-coloring",
25 cl::desc("enable safe stack coloring"),
26 cl::Hidden, cl::init(false));
28 const StackColoring::LiveRange &StackColoring::getLiveRange(AllocaInst *AI) {
29 const auto IT = AllocaNumbering.find(AI);
30 assert(IT != AllocaNumbering.end());
31 return LiveRanges[IT->second];
34 bool StackColoring::readMarker(Instruction *I, bool *IsStart) {
35 auto *II = dyn_cast<IntrinsicInst>(I);
36 if (!II || (II->getIntrinsicID() != Intrinsic::lifetime_start &&
37 II->getIntrinsicID() != Intrinsic::lifetime_end))
40 *IsStart = II->getIntrinsicID() == Intrinsic::lifetime_start;
44 void StackColoring::removeAllMarkers() {
45 for (auto *I : Markers) {
46 auto *Op = dyn_cast<Instruction>(I->getOperand(1));
48 // Remove the operand bitcast, too, if it has no more uses left.
49 if (Op && Op->use_empty())
50 Op->eraseFromParent();
54 void StackColoring::collectMarkers() {
55 InterestingAllocas.resize(NumAllocas);
56 DenseMap<BasicBlock *, SmallDenseMap<Instruction *, Marker>> BBMarkerSet;
58 // Compute the set of start/end markers per basic block.
59 for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) {
60 AllocaInst *AI = Allocas[AllocaNo];
61 SmallVector<Instruction *, 8> WorkList;
62 WorkList.push_back(AI);
63 while (!WorkList.empty()) {
64 Instruction *I = WorkList.pop_back_val();
65 for (User *U : I->users()) {
66 if (auto *BI = dyn_cast<BitCastInst>(U)) {
67 WorkList.push_back(BI);
70 auto *UI = dyn_cast<Instruction>(U);
74 if (!readMarker(UI, &IsStart))
77 InterestingAllocas.set(AllocaNo);
78 BBMarkerSet[UI->getParent()][UI] = {AllocaNo, IsStart};
79 Markers.push_back(UI);
84 // Compute instruction numbering. Only the following instructions are
86 // * Basic block entries
88 // For each basic block, compute
89 // * the list of markers in the instruction order
90 // * the sets of allocas whose lifetime starts or ends in this BB
91 DEBUG(dbgs() << "Instructions:\n");
93 for (BasicBlock *BB : depth_first(&F)) {
94 DEBUG(dbgs() << " " << InstNo << ": BB " << BB->getName() << "\n");
95 unsigned BBStart = InstNo++;
97 BlockLifetimeInfo &BlockInfo = BlockLiveness[BB];
98 BlockInfo.Begin.resize(NumAllocas);
99 BlockInfo.End.resize(NumAllocas);
100 BlockInfo.LiveIn.resize(NumAllocas);
101 BlockInfo.LiveOut.resize(NumAllocas);
103 auto &BlockMarkerSet = BBMarkerSet[BB];
104 if (BlockMarkerSet.empty()) {
105 unsigned BBEnd = InstNo;
106 BlockInstRange[BB] = std::make_pair(BBStart, BBEnd);
110 auto ProcessMarker = [&](Instruction *I, const Marker &M) {
111 DEBUG(dbgs() << " " << InstNo << ": "
112 << (M.IsStart ? "start " : "end ") << M.AllocaNo << ", "
115 BBMarkers[BB].push_back({InstNo, M});
117 InstructionNumbering[I] = InstNo++;
120 if (BlockInfo.End.test(M.AllocaNo))
121 BlockInfo.End.reset(M.AllocaNo);
122 BlockInfo.Begin.set(M.AllocaNo);
124 if (BlockInfo.Begin.test(M.AllocaNo))
125 BlockInfo.Begin.reset(M.AllocaNo);
126 BlockInfo.End.set(M.AllocaNo);
130 if (BlockMarkerSet.size() == 1) {
131 ProcessMarker(BlockMarkerSet.begin()->getFirst(),
132 BlockMarkerSet.begin()->getSecond());
134 // Scan the BB to determine the marker order.
135 for (Instruction &I : *BB) {
136 auto It = BlockMarkerSet.find(&I);
137 if (It == BlockMarkerSet.end())
139 ProcessMarker(&I, It->getSecond());
143 unsigned BBEnd = InstNo;
144 BlockInstRange[BB] = std::make_pair(BBStart, BBEnd);
149 void StackColoring::calculateLocalLiveness() {
154 for (BasicBlock *BB : depth_first(&F)) {
155 BlockLifetimeInfo &BlockInfo = BlockLiveness[BB];
157 // Compute LiveIn by unioning together the LiveOut sets of all preds.
158 BitVector LocalLiveIn;
159 for (auto *PredBB : predecessors(BB)) {
160 LivenessMap::const_iterator I = BlockLiveness.find(PredBB);
161 assert(I != BlockLiveness.end() && "Predecessor not found");
162 LocalLiveIn |= I->second.LiveOut;
165 // Compute LiveOut by subtracting out lifetimes that end in this
166 // block, then adding in lifetimes that begin in this block. If
167 // we have both BEGIN and END markers in the same basic block
168 // then we know that the BEGIN marker comes after the END,
169 // because we already handle the case where the BEGIN comes
170 // before the END when collecting the markers (and building the
171 // BEGIN/END vectors).
172 BitVector LocalLiveOut = LocalLiveIn;
173 LocalLiveOut.reset(BlockInfo.End);
174 LocalLiveOut |= BlockInfo.Begin;
176 // Update block LiveIn set, noting whether it has changed.
177 if (LocalLiveIn.test(BlockInfo.LiveIn)) {
179 BlockInfo.LiveIn |= LocalLiveIn;
182 // Update block LiveOut set, noting whether it has changed.
183 if (LocalLiveOut.test(BlockInfo.LiveOut)) {
185 BlockInfo.LiveOut |= LocalLiveOut;
191 void StackColoring::calculateLiveIntervals() {
192 for (auto IT : BlockLiveness) {
193 BasicBlock *BB = IT.getFirst();
194 BlockLifetimeInfo &BlockInfo = IT.getSecond();
195 unsigned BBStart, BBEnd;
196 std::tie(BBStart, BBEnd) = BlockInstRange[BB];
198 BitVector Started, Ended;
199 Started.resize(NumAllocas);
200 Ended.resize(NumAllocas);
201 SmallVector<unsigned, 8> Start;
202 Start.resize(NumAllocas);
204 // LiveIn ranges start at the first instruction.
205 for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) {
206 if (BlockInfo.LiveIn.test(AllocaNo)) {
207 Started.set(AllocaNo);
208 Start[AllocaNo] = BBStart;
212 for (auto &It : BBMarkers[BB]) {
213 unsigned InstNo = It.first;
214 bool IsStart = It.second.IsStart;
215 unsigned AllocaNo = It.second.AllocaNo;
218 assert(!Started.test(AllocaNo) || Start[AllocaNo] == BBStart);
219 if (!Started.test(AllocaNo)) {
220 Started.set(AllocaNo);
221 Ended.reset(AllocaNo);
222 Start[AllocaNo] = InstNo;
225 assert(!Ended.test(AllocaNo));
226 if (Started.test(AllocaNo)) {
227 LiveRanges[AllocaNo].AddRange(Start[AllocaNo], InstNo);
228 Started.reset(AllocaNo);
234 for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo)
235 if (Started.test(AllocaNo))
236 LiveRanges[AllocaNo].AddRange(Start[AllocaNo], BBEnd);
240 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
241 LLVM_DUMP_METHOD void StackColoring::dumpAllocas() {
242 dbgs() << "Allocas:\n";
243 for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo)
244 dbgs() << " " << AllocaNo << ": " << *Allocas[AllocaNo] << "\n";
247 LLVM_DUMP_METHOD void StackColoring::dumpBlockLiveness() {
248 dbgs() << "Block liveness:\n";
249 for (auto IT : BlockLiveness) {
250 BasicBlock *BB = IT.getFirst();
251 BlockLifetimeInfo &BlockInfo = BlockLiveness[BB];
252 auto BlockRange = BlockInstRange[BB];
253 dbgs() << " BB [" << BlockRange.first << ", " << BlockRange.second
254 << "): begin " << BlockInfo.Begin << ", end " << BlockInfo.End
255 << ", livein " << BlockInfo.LiveIn << ", liveout "
256 << BlockInfo.LiveOut << "\n";
260 LLVM_DUMP_METHOD void StackColoring::dumpLiveRanges() {
261 dbgs() << "Alloca liveness:\n";
262 for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) {
263 LiveRange &Range = LiveRanges[AllocaNo];
264 dbgs() << " " << AllocaNo << ": " << Range << "\n";
269 void StackColoring::run() {
270 DEBUG(dumpAllocas());
272 for (unsigned I = 0; I < NumAllocas; ++I)
273 AllocaNumbering[Allocas[I]] = I;
274 LiveRanges.resize(NumAllocas);
279 for (auto &R : LiveRanges) {
286 for (auto &R : LiveRanges)
287 R.SetMaximum(NumInst);
288 for (unsigned I = 0; I < NumAllocas; ++I)
289 if (!InterestingAllocas.test(I))
290 LiveRanges[I] = getFullLiveRange();
292 calculateLocalLiveness();
293 DEBUG(dumpBlockLiveness());
294 calculateLiveIntervals();
295 DEBUG(dumpLiveRanges());