summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2016-07-20 20:17:13 +0000
committerDavide Italiano <davide@freebsd.org>2016-07-20 20:17:13 +0000
commit15ff2d6d0cc422dc672f3726f05ac98f85992e42 (patch)
treeaf90cb5171c1931b412e58842f863f54ea04bb53 /llvm/lib/Transforms
parenta088bce959182f938a1643c1301384bcc4d35da6 (diff)
downloadbcm5719-llvm-15ff2d6d0cc422dc672f3726f05ac98f85992e42.tar.gz
bcm5719-llvm-15ff2d6d0cc422dc672f3726f05ac98f85992e42.zip
[SCCP] Zap multiple return values.
We can replace the return values with undef if we replaced all the call uses with a constant/undef. Differential Revision: https://reviews.llvm.org/D22336 llvm-svn: 276174
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/SCCP.cpp50
1 files changed, 41 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp
index ea852147a7c..355009176d8 100644
--- a/llvm/lib/Transforms/Scalar/SCCP.cpp
+++ b/llvm/lib/Transforms/Scalar/SCCP.cpp
@@ -300,6 +300,12 @@ public:
return TrackedGlobals;
}
+ /// getMRVFunctionsTracked - Get the set of functions which return multiple
+ /// values tracked by the pass.
+ const SmallPtrSet<Function *, 16> getMRVFunctionsTracked() {
+ return MRVFunctionsTracked;
+ }
+
void markOverdefined(Value *V) {
assert(!V->getType()->isStructTy() &&
"structs should use markAnythingOverdefined");
@@ -316,6 +322,20 @@ public:
markOverdefined(V);
}
+ // isStructLatticeConstant - Return true if all the lattice values
+ // corresponding to elements of the structure are not overdefined,
+ // false otherwise.
+ bool isStructLatticeConstant(Function *F, StructType *STy) {
+ for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+ const auto &It = TrackedMultipleRetVals.find(std::make_pair(F, i));
+ assert(It != TrackedMultipleRetVals.end());
+ LatticeVal LV = It->second;
+ if (LV.isOverdefined())
+ return false;
+ }
+ return true;
+ }
+
private:
// pushToWorkList - Helper for markConstant/markForcedConstant
void pushToWorkList(LatticeVal &IV, Value *V) {
@@ -1690,6 +1710,19 @@ static bool AddressIsTaken(const GlobalValue *GV) {
return false;
}
+static void findReturnsToZap(Function &F,
+ SmallPtrSet<Function *, 32> &AddressTakenFunctions,
+ SmallVector<ReturnInst *, 8> &ReturnsToZap) {
+ // We can only do this if we know that nothing else can call the function.
+ if (!F.hasLocalLinkage() || AddressTakenFunctions.count(&F))
+ return;
+
+ for (BasicBlock &BB : F)
+ if (ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator()))
+ if (!isa<UndefValue>(RI->getOperand(0)))
+ ReturnsToZap.push_back(RI);
+}
+
static bool runIPSCCP(Module &M, const DataLayout &DL,
const TargetLibraryInfo *TLI) {
SCCPSolver Solver(DL, TLI);
@@ -1866,21 +1899,20 @@ static bool runIPSCCP(Module &M, const DataLayout &DL,
// whether other functions are optimizable.
SmallVector<ReturnInst*, 8> ReturnsToZap;
- // TODO: Process multiple value ret instructions also.
const DenseMap<Function*, LatticeVal> &RV = Solver.getTrackedRetVals();
for (const auto &I : RV) {
Function *F = I.first;
if (I.second.isOverdefined() || F->getReturnType()->isVoidTy())
continue;
+ findReturnsToZap(*F, AddressTakenFunctions, ReturnsToZap);
+ }
- // We can only do this if we know that nothing else can call the function.
- if (!F->hasLocalLinkage() || AddressTakenFunctions.count(F))
- continue;
-
- for (BasicBlock &BB : *F)
- if (ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator()))
- if (!isa<UndefValue>(RI->getOperand(0)))
- ReturnsToZap.push_back(RI);
+ for (const auto &F : Solver.getMRVFunctionsTracked()) {
+ assert(F->getReturnType()->isStructTy() &&
+ "The return type should be a struct");
+ StructType *STy = cast<StructType>(F->getReturnType());
+ if (Solver.isStructLatticeConstant(F, STy))
+ findReturnsToZap(*F, AddressTakenFunctions, ReturnsToZap);
}
// Zap all returns which we've identified as zap to change.
OpenPOWER on IntegriCloud