Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Transforms/Scalar/ConstantProp.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ConstantProp.cpp - Code to perform Simple Constant Propagation -----===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file implements constant propagation and merging:
10
//
11
// Specifically, this:
12
//   * Converts instructions like "add int 1, 2" into 3
13
//
14
// Notice that:
15
//   * This pass has a habit of making definitions be dead.  It is a good idea
16
//     to run a DIE pass sometime after running this pass.
17
//
18
//===----------------------------------------------------------------------===//
19
20
#include "llvm/ADT/SmallPtrSet.h"
21
#include "llvm/ADT/SmallVector.h"
22
#include "llvm/ADT/Statistic.h"
23
#include "llvm/Analysis/ConstantFolding.h"
24
#include "llvm/Analysis/TargetLibraryInfo.h"
25
#include "llvm/IR/Constant.h"
26
#include "llvm/IR/InstIterator.h"
27
#include "llvm/IR/Instruction.h"
28
#include "llvm/Pass.h"
29
#include "llvm/Support/DebugCounter.h"
30
#include "llvm/Transforms/Scalar.h"
31
#include "llvm/Transforms/Utils/Local.h"
32
using namespace llvm;
33
34
#define DEBUG_TYPE "constprop"
35
36
STATISTIC(NumInstKilled, "Number of instructions killed");
37
DEBUG_COUNTER(CPCounter, "constprop-transform",
38
              "Controls which instructions are killed");
39
40
namespace {
41
  struct ConstantPropagation : public FunctionPass {
42
    static char ID; // Pass identification, replacement for typeid
43
919
    ConstantPropagation() : FunctionPass(ID) {
44
919
      initializeConstantPropagationPass(*PassRegistry::getPassRegistry());
45
919
    }
46
47
    bool runOnFunction(Function &F) override;
48
49
912
    void getAnalysisUsage(AnalysisUsage &AU) const override {
50
912
      AU.setPreservesCFG();
51
912
      AU.addRequired<TargetLibraryInfoWrapperPass>();
52
912
    }
53
  };
54
}
55
56
char ConstantPropagation::ID = 0;
57
36.0k
INITIALIZE_PASS_BEGIN(ConstantPropagation, "constprop",
58
36.0k
                "Simple constant propagation", false, false)
59
36.0k
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
60
36.0k
INITIALIZE_PASS_END(ConstantPropagation, "constprop",
61
                "Simple constant propagation", false, false)
62
63
869
FunctionPass *llvm::createConstantPropagationPass() {
64
869
  return new ConstantPropagation();
65
869
}
66
67
3.67k
bool ConstantPropagation::runOnFunction(Function &F) {
68
3.67k
  if (skipFunction(F))
69
10
    return false;
70
3.66k
71
3.66k
  // Initialize the worklist to all of the instructions ready to process...
72
3.66k
  SmallPtrSet<Instruction *, 16> WorkList;
73
3.66k
  // The SmallVector of WorkList ensures that we do iteration at stable order.
74
3.66k
  // We use two containers rather than one SetVector, since remove is
75
3.66k
  // linear-time, and we don't care enough to remove from Vec.
76
3.66k
  SmallVector<Instruction *, 16> WorkListVec;
77
27.6k
  for (Instruction &I : instructions(&F)) {
78
27.6k
    WorkList.insert(&I);
79
27.6k
    WorkListVec.push_back(&I);
80
27.6k
  }
81
3.66k
82
3.66k
  bool Changed = false;
83
3.66k
  const DataLayout &DL = F.getParent()->getDataLayout();
84
3.66k
  TargetLibraryInfo *TLI =
85
3.66k
      &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
86
3.66k
87
7.33k
  while (!WorkList.empty()) {
88
3.66k
    SmallVector<Instruction*, 16> NewWorkListVec;
89
27.6k
    for (auto *I : WorkListVec) {
90
27.6k
      WorkList.erase(I); // Remove element from the worklist...
91
27.6k
92
27.6k
      if (!I->use_empty()) // Don't muck with dead instructions...
93
18.7k
        if (Constant *C = ConstantFoldInstruction(I, DL, TLI)) {
94
582
          if (!DebugCounter::shouldExecute(CPCounter))
95
0
            continue;
96
582
97
582
          // Add all of the users of this instruction to the worklist, they might
98
582
          // be constant propagatable now...
99
626
          
for (User *U : I->users())582
{
100
626
            // If user not in the set, then add it to the vector.
101
626
            if (WorkList.insert(cast<Instruction>(U)).second)
102
0
              NewWorkListVec.push_back(cast<Instruction>(U));
103
626
          }
104
582
105
582
          // Replace all of the uses of a variable with uses of the constant.
106
582
          I->replaceAllUsesWith(C);
107
582
108
582
          if (isInstructionTriviallyDead(I, TLI)) {
109
582
            I->eraseFromParent();
110
582
            ++NumInstKilled;
111
582
          }
112
582
113
582
          // We made a change to the function...
114
582
          Changed = true;
115
582
        }
116
27.6k
    }
117
3.66k
    WorkListVec = std::move(NewWorkListVec);
118
3.66k
  }
119
3.66k
  return Changed;
120
3.66k
}