diff options
Diffstat (limited to 'llvm/lib/CodeGen/SafeStackColoring.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SafeStackColoring.cpp | 310 |
1 files changed, 0 insertions, 310 deletions
diff --git a/llvm/lib/CodeGen/SafeStackColoring.cpp b/llvm/lib/CodeGen/SafeStackColoring.cpp deleted file mode 100644 index 04a5c4b6d892f..0000000000000 --- a/llvm/lib/CodeGen/SafeStackColoring.cpp +++ /dev/null @@ -1,310 +0,0 @@ -//===- SafeStackColoring.cpp - SafeStack frame coloring -------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "SafeStackColoring.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DepthFirstIterator.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Config/llvm-config.h" -#include "llvm/IR/BasicBlock.h" -#include "llvm/IR/CFG.h" -#include "llvm/IR/Instruction.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/IntrinsicInst.h" -#include "llvm/IR/Intrinsics.h" -#include "llvm/IR/User.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" -#include <cassert> -#include <tuple> -#include <utility> - -using namespace llvm; -using namespace llvm::safestack; - -#define DEBUG_TYPE "safestackcoloring" - -// Disabled by default due to PR32143. -static cl::opt<bool> ClColoring("safe-stack-coloring", - cl::desc("enable safe stack coloring"), - cl::Hidden, cl::init(false)); - -const StackColoring::LiveRange &StackColoring::getLiveRange(AllocaInst *AI) { - const auto IT = AllocaNumbering.find(AI); - assert(IT != AllocaNumbering.end()); - return LiveRanges[IT->second]; -} - -bool StackColoring::readMarker(Instruction *I, bool *IsStart) { - if (!I->isLifetimeStartOrEnd()) - return false; - - auto *II = cast<IntrinsicInst>(I); - *IsStart = II->getIntrinsicID() == Intrinsic::lifetime_start; - return true; -} - -void StackColoring::removeAllMarkers() { - for (auto *I : Markers) { - auto *Op = dyn_cast<Instruction>(I->getOperand(1)); - I->eraseFromParent(); - // Remove the operand bitcast, too, if it has no more uses left. - if (Op && Op->use_empty()) - Op->eraseFromParent(); - } -} - -void StackColoring::collectMarkers() { - InterestingAllocas.resize(NumAllocas); - DenseMap<BasicBlock *, SmallDenseMap<Instruction *, Marker>> BBMarkerSet; - - // Compute the set of start/end markers per basic block. - for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) { - AllocaInst *AI = Allocas[AllocaNo]; - SmallVector<Instruction *, 8> WorkList; - WorkList.push_back(AI); - while (!WorkList.empty()) { - Instruction *I = WorkList.pop_back_val(); - for (User *U : I->users()) { - if (auto *BI = dyn_cast<BitCastInst>(U)) { - WorkList.push_back(BI); - continue; - } - auto *UI = dyn_cast<Instruction>(U); - if (!UI) - continue; - bool IsStart; - if (!readMarker(UI, &IsStart)) - continue; - if (IsStart) - InterestingAllocas.set(AllocaNo); - BBMarkerSet[UI->getParent()][UI] = {AllocaNo, IsStart}; - Markers.push_back(UI); - } - } - } - - // Compute instruction numbering. Only the following instructions are - // considered: - // * Basic block entries - // * Lifetime markers - // For each basic block, compute - // * the list of markers in the instruction order - // * the sets of allocas whose lifetime starts or ends in this BB - LLVM_DEBUG(dbgs() << "Instructions:\n"); - unsigned InstNo = 0; - for (BasicBlock *BB : depth_first(&F)) { - LLVM_DEBUG(dbgs() << " " << InstNo << ": BB " << BB->getName() << "\n"); - unsigned BBStart = InstNo++; - - BlockLifetimeInfo &BlockInfo = BlockLiveness[BB]; - BlockInfo.Begin.resize(NumAllocas); - BlockInfo.End.resize(NumAllocas); - BlockInfo.LiveIn.resize(NumAllocas); - BlockInfo.LiveOut.resize(NumAllocas); - - auto &BlockMarkerSet = BBMarkerSet[BB]; - if (BlockMarkerSet.empty()) { - unsigned BBEnd = InstNo; - BlockInstRange[BB] = std::make_pair(BBStart, BBEnd); - continue; - } - - auto ProcessMarker = [&](Instruction *I, const Marker &M) { - LLVM_DEBUG(dbgs() << " " << InstNo << ": " - << (M.IsStart ? "start " : "end ") << M.AllocaNo - << ", " << *I << "\n"); - - BBMarkers[BB].push_back({InstNo, M}); - - InstructionNumbering[I] = InstNo++; - - if (M.IsStart) { - if (BlockInfo.End.test(M.AllocaNo)) - BlockInfo.End.reset(M.AllocaNo); - BlockInfo.Begin.set(M.AllocaNo); - } else { - if (BlockInfo.Begin.test(M.AllocaNo)) - BlockInfo.Begin.reset(M.AllocaNo); - BlockInfo.End.set(M.AllocaNo); - } - }; - - if (BlockMarkerSet.size() == 1) { - ProcessMarker(BlockMarkerSet.begin()->getFirst(), - BlockMarkerSet.begin()->getSecond()); - } else { - // Scan the BB to determine the marker order. - for (Instruction &I : *BB) { - auto It = BlockMarkerSet.find(&I); - if (It == BlockMarkerSet.end()) - continue; - ProcessMarker(&I, It->getSecond()); - } - } - - unsigned BBEnd = InstNo; - BlockInstRange[BB] = std::make_pair(BBStart, BBEnd); - } - NumInst = InstNo; -} - -void StackColoring::calculateLocalLiveness() { - bool changed = true; - while (changed) { - changed = false; - - for (BasicBlock *BB : depth_first(&F)) { - BlockLifetimeInfo &BlockInfo = BlockLiveness[BB]; - - // Compute LiveIn by unioning together the LiveOut sets of all preds. - BitVector LocalLiveIn; - for (auto *PredBB : predecessors(BB)) { - LivenessMap::const_iterator I = BlockLiveness.find(PredBB); - // If a predecessor is unreachable, ignore it. - if (I == BlockLiveness.end()) - continue; - LocalLiveIn |= I->second.LiveOut; - } - - // Compute LiveOut by subtracting out lifetimes that end in this - // block, then adding in lifetimes that begin in this block. If - // we have both BEGIN and END markers in the same basic block - // then we know that the BEGIN marker comes after the END, - // because we already handle the case where the BEGIN comes - // before the END when collecting the markers (and building the - // BEGIN/END vectors). - BitVector LocalLiveOut = LocalLiveIn; - LocalLiveOut.reset(BlockInfo.End); - LocalLiveOut |= BlockInfo.Begin; - - // Update block LiveIn set, noting whether it has changed. - if (LocalLiveIn.test(BlockInfo.LiveIn)) { - changed = true; - BlockInfo.LiveIn |= LocalLiveIn; - } - - // Update block LiveOut set, noting whether it has changed. - if (LocalLiveOut.test(BlockInfo.LiveOut)) { - changed = true; - BlockInfo.LiveOut |= LocalLiveOut; - } - } - } // while changed. -} - -void StackColoring::calculateLiveIntervals() { - for (auto IT : BlockLiveness) { - BasicBlock *BB = IT.getFirst(); - BlockLifetimeInfo &BlockInfo = IT.getSecond(); - unsigned BBStart, BBEnd; - std::tie(BBStart, BBEnd) = BlockInstRange[BB]; - - BitVector Started, Ended; - Started.resize(NumAllocas); - Ended.resize(NumAllocas); - SmallVector<unsigned, 8> Start; - Start.resize(NumAllocas); - - // LiveIn ranges start at the first instruction. - for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) { - if (BlockInfo.LiveIn.test(AllocaNo)) { - Started.set(AllocaNo); - Start[AllocaNo] = BBStart; - } - } - - for (auto &It : BBMarkers[BB]) { - unsigned InstNo = It.first; - bool IsStart = It.second.IsStart; - unsigned AllocaNo = It.second.AllocaNo; - - if (IsStart) { - assert(!Started.test(AllocaNo) || Start[AllocaNo] == BBStart); - if (!Started.test(AllocaNo)) { - Started.set(AllocaNo); - Ended.reset(AllocaNo); - Start[AllocaNo] = InstNo; - } - } else { - assert(!Ended.test(AllocaNo)); - if (Started.test(AllocaNo)) { - LiveRanges[AllocaNo].AddRange(Start[AllocaNo], InstNo); - Started.reset(AllocaNo); - } - Ended.set(AllocaNo); - } - } - - for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) - if (Started.test(AllocaNo)) - LiveRanges[AllocaNo].AddRange(Start[AllocaNo], BBEnd); - } -} - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD void StackColoring::dumpAllocas() { - dbgs() << "Allocas:\n"; - for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) - dbgs() << " " << AllocaNo << ": " << *Allocas[AllocaNo] << "\n"; -} - -LLVM_DUMP_METHOD void StackColoring::dumpBlockLiveness() { - dbgs() << "Block liveness:\n"; - for (auto IT : BlockLiveness) { - BasicBlock *BB = IT.getFirst(); - BlockLifetimeInfo &BlockInfo = BlockLiveness[BB]; - auto BlockRange = BlockInstRange[BB]; - dbgs() << " BB [" << BlockRange.first << ", " << BlockRange.second - << "): begin " << BlockInfo.Begin << ", end " << BlockInfo.End - << ", livein " << BlockInfo.LiveIn << ", liveout " - << BlockInfo.LiveOut << "\n"; - } -} - -LLVM_DUMP_METHOD void StackColoring::dumpLiveRanges() { - dbgs() << "Alloca liveness:\n"; - for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) { - LiveRange &Range = LiveRanges[AllocaNo]; - dbgs() << " " << AllocaNo << ": " << Range << "\n"; - } -} -#endif - -void StackColoring::run() { - LLVM_DEBUG(dumpAllocas()); - - for (unsigned I = 0; I < NumAllocas; ++I) - AllocaNumbering[Allocas[I]] = I; - LiveRanges.resize(NumAllocas); - - collectMarkers(); - - if (!ClColoring) { - for (auto &R : LiveRanges) { - R.SetMaximum(1); - R.AddRange(0, 1); - } - return; - } - - for (auto &R : LiveRanges) - R.SetMaximum(NumInst); - for (unsigned I = 0; I < NumAllocas; ++I) - if (!InterestingAllocas.test(I)) - LiveRanges[I] = getFullLiveRange(); - - calculateLocalLiveness(); - LLVM_DEBUG(dumpBlockLiveness()); - calculateLiveIntervals(); - LLVM_DEBUG(dumpLiveRanges()); -} |