2021-12-22 02:21:41 +08:00
|
|
|
//===- bolt/Passes/StackReachingUses.cpp ----------------------------------===//
|
2017-05-02 07:52:54 +08:00
|
|
|
//
|
2021-03-16 09:04:18 +08:00
|
|
|
// 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
|
2017-05-02 07:52:54 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2021-12-22 02:21:41 +08:00
|
|
|
// This file implements the StackReachingUses class.
|
|
|
|
//
|
2017-05-02 07:52:54 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2021-12-22 02:21:41 +08:00
|
|
|
|
2021-10-09 02:47:10 +08:00
|
|
|
#include "bolt/Passes/StackReachingUses.h"
|
|
|
|
#include "bolt/Passes/FrameAnalysis.h"
|
2017-05-02 07:52:54 +08:00
|
|
|
|
|
|
|
#define DEBUG_TYPE "sru"
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
namespace bolt {
|
|
|
|
|
2017-06-23 07:34:01 +08:00
|
|
|
bool StackReachingUses::isLoadedInDifferentReg(const FrameIndexEntry &StoreFIE,
|
|
|
|
ExprIterator Candidates) const {
|
|
|
|
for (auto I = Candidates; I != expr_end(); ++I) {
|
|
|
|
const MCInst *ReachingInst = *I;
|
2021-04-08 15:19:26 +08:00
|
|
|
if (ErrorOr<const FrameIndexEntry &> FIEY = FA.getFIEFor(*ReachingInst)) {
|
2017-06-23 07:34:01 +08:00
|
|
|
assert(FIEY->IsLoad == 1);
|
|
|
|
if (StoreFIE.StackOffset + StoreFIE.Size > FIEY->StackOffset &&
|
|
|
|
StoreFIE.StackOffset < FIEY->StackOffset + FIEY->Size &&
|
2021-12-29 08:36:17 +08:00
|
|
|
StoreFIE.RegOrImm != FIEY->RegOrImm)
|
2017-06-23 07:34:01 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-05-02 07:52:54 +08:00
|
|
|
bool StackReachingUses::isStoreUsed(const FrameIndexEntry &StoreFIE,
|
|
|
|
ExprIterator Candidates,
|
|
|
|
bool IncludeLocalAccesses) const {
|
|
|
|
for (auto I = Candidates; I != expr_end(); ++I) {
|
|
|
|
const MCInst *ReachingInst = *I;
|
|
|
|
if (IncludeLocalAccesses) {
|
2021-04-08 15:19:26 +08:00
|
|
|
if (ErrorOr<const FrameIndexEntry &> FIEY = FA.getFIEFor(*ReachingInst)) {
|
2017-05-02 07:52:54 +08:00
|
|
|
assert(FIEY->IsLoad == 1);
|
|
|
|
if (StoreFIE.StackOffset + StoreFIE.Size > FIEY->StackOffset &&
|
2021-12-29 08:36:17 +08:00
|
|
|
StoreFIE.StackOffset < FIEY->StackOffset + FIEY->Size)
|
2017-05-02 07:52:54 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2021-04-08 15:19:26 +08:00
|
|
|
ErrorOr<const ArgAccesses &> Args = FA.getArgAccessesFor(*ReachingInst);
|
2017-05-02 07:52:54 +08:00
|
|
|
if (!Args)
|
|
|
|
continue;
|
2021-12-29 08:36:17 +08:00
|
|
|
if (Args->AssumeEverything)
|
2017-05-02 07:52:54 +08:00
|
|
|
return true;
|
2021-12-29 08:36:17 +08:00
|
|
|
|
|
|
|
for (ArgInStackAccess FIEY : Args->Set)
|
2017-05-02 07:52:54 +08:00
|
|
|
if (StoreFIE.StackOffset + StoreFIE.Size > FIEY.StackOffset &&
|
2021-12-29 08:36:17 +08:00
|
|
|
StoreFIE.StackOffset < FIEY.StackOffset + FIEY.Size)
|
2017-05-02 07:52:54 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void StackReachingUses::preflight() {
|
2020-12-02 08:29:39 +08:00
|
|
|
LLVM_DEBUG(dbgs() << "Starting StackReachingUses on \"" << Func.getPrintName()
|
|
|
|
<< "\"\n");
|
2017-05-02 07:52:54 +08:00
|
|
|
|
|
|
|
// Populate our universe of tracked expressions. We are interested in
|
|
|
|
// tracking reaching loads from frame position at any given point of the
|
|
|
|
// program.
|
2021-04-08 15:19:26 +08:00
|
|
|
for (BinaryBasicBlock &BB : Func) {
|
|
|
|
for (MCInst &Inst : BB) {
|
|
|
|
if (ErrorOr<const FrameIndexEntry &> FIE = FA.getFIEFor(Inst)) {
|
2017-05-02 07:52:54 +08:00
|
|
|
if (FIE->IsLoad == true) {
|
|
|
|
Expressions.push_back(&Inst);
|
|
|
|
ExprToIdx[&Inst] = NumInstrs++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2021-04-08 15:19:26 +08:00
|
|
|
ErrorOr<const ArgAccesses &> AA = FA.getArgAccessesFor(Inst);
|
2017-05-02 07:52:54 +08:00
|
|
|
if (AA && (!AA->Set.empty() || AA->AssumeEverything)) {
|
|
|
|
Expressions.push_back(&Inst);
|
|
|
|
ExprToIdx[&Inst] = NumInstrs++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool StackReachingUses::doesXKillsY(const MCInst *X, const MCInst *Y) {
|
|
|
|
// if X is a store to the same stack location and the bytes fetched is a
|
|
|
|
// superset of those bytes affected by the load in Y, return true
|
2021-04-08 15:19:26 +08:00
|
|
|
ErrorOr<const FrameIndexEntry &> FIEX = FA.getFIEFor(*X);
|
|
|
|
ErrorOr<const FrameIndexEntry &> FIEY = FA.getFIEFor(*Y);
|
2017-05-02 07:52:54 +08:00
|
|
|
if (FIEX && FIEY) {
|
2018-03-13 11:24:01 +08:00
|
|
|
if (FIEX->IsSimple == true && FIEY->IsSimple == true &&
|
|
|
|
FIEX->IsStore == true && FIEY->IsLoad == true &&
|
2017-05-02 07:52:54 +08:00
|
|
|
FIEX->StackOffset <= FIEY->StackOffset &&
|
|
|
|
FIEX->StackOffset + FIEX->Size >= FIEY->StackOffset + FIEY->Size)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
BitVector StackReachingUses::computeNext(const MCInst &Point,
|
|
|
|
const BitVector &Cur) {
|
|
|
|
BitVector Next = Cur;
|
|
|
|
// Kill
|
|
|
|
for (auto I = expr_begin(Next), E = expr_end(); I != E; ++I) {
|
|
|
|
assert(*I != nullptr && "Lost pointers");
|
|
|
|
if (doesXKillsY(&Point, *I)) {
|
2020-12-02 08:29:39 +08:00
|
|
|
LLVM_DEBUG(dbgs() << "\t\t\tKilling ");
|
|
|
|
LLVM_DEBUG((*I)->dump());
|
2017-05-02 07:52:54 +08:00
|
|
|
Next.reset(I.getBitVectorIndex());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// Gen
|
2021-04-08 15:19:26 +08:00
|
|
|
if (ErrorOr<const FrameIndexEntry &> FIE = FA.getFIEFor(Point)) {
|
2017-05-02 07:52:54 +08:00
|
|
|
if (FIE->IsLoad == true)
|
|
|
|
Next.set(ExprToIdx[&Point]);
|
|
|
|
}
|
2021-04-08 15:19:26 +08:00
|
|
|
ErrorOr<const ArgAccesses &> AA = FA.getArgAccessesFor(Point);
|
2017-05-02 07:52:54 +08:00
|
|
|
if (AA && (!AA->Set.empty() || AA->AssumeEverything))
|
|
|
|
Next.set(ExprToIdx[&Point]);
|
|
|
|
return Next;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace bolt
|
|
|
|
} // namespace llvm
|