diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-06-01 20:58:36 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-06-01 20:58:36 +0000 | 
| commit | f382538d471e38a9b98f016c4caebd24c8d60b62 (patch) | |
| tree | d30f3d58b1044b5355d50c17a6a96c6a0b35703a /lib/Transforms/Scalar | |
| parent | ee2f195dd3e40f49698ca4dc2666ec09c770e80d (diff) | |
Notes
Diffstat (limited to 'lib/Transforms/Scalar')
| -rw-r--r-- | lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | 9 | ||||
| -rw-r--r-- | lib/Transforms/Scalar/GVN.cpp | 164 | ||||
| -rw-r--r-- | lib/Transforms/Scalar/LowerExpectIntrinsic.cpp | 16 | ||||
| -rw-r--r-- | lib/Transforms/Scalar/NewGVN.cpp | 38 | 
4 files changed, 53 insertions, 174 deletions
diff --git a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index ee493a8ec7e1..7b625b9b136e 100644 --- a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -305,7 +305,7 @@ static bool processSwitch(SwitchInst *SI, LazyValueInfo *LVI) {  /// Infer nonnull attributes for the arguments at the specified callsite.  static bool processCallSite(CallSite CS, LazyValueInfo *LVI) { -  SmallVector<unsigned, 4> Indices; +  SmallVector<unsigned, 4> ArgNos;    unsigned ArgNo = 0;    for (Value *V : CS.args()) { @@ -318,18 +318,19 @@ static bool processCallSite(CallSite CS, LazyValueInfo *LVI) {          LVI->getPredicateAt(ICmpInst::ICMP_EQ, V,                              ConstantPointerNull::get(Type),                              CS.getInstruction()) == LazyValueInfo::False) -      Indices.push_back(ArgNo + AttributeList::FirstArgIndex); +      ArgNos.push_back(ArgNo);      ArgNo++;    }    assert(ArgNo == CS.arg_size() && "sanity check"); -  if (Indices.empty()) +  if (ArgNos.empty())      return false;    AttributeList AS = CS.getAttributes();    LLVMContext &Ctx = CS.getInstruction()->getContext(); -  AS = AS.addAttribute(Ctx, Indices, Attribute::get(Ctx, Attribute::NonNull)); +  AS = AS.addParamAttribute(Ctx, ArgNos, +                            Attribute::get(Ctx, Attribute::NonNull));    CS.setAttributes(AS);    return true; diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 0d6e0538261d..0490d93f6455 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -80,10 +80,9 @@ MaxRecurseDepth("max-recurse-depth", cl::Hidden, cl::init(1000), cl::ZeroOrMore,  struct llvm::GVN::Expression {    uint32_t opcode;    Type *type; -  bool commutative;    SmallVector<uint32_t, 4> varargs; -  Expression(uint32_t o = ~2U) : opcode(o), commutative(false) {} +  Expression(uint32_t o = ~2U) : opcode(o) {}    bool operator==(const Expression &other) const {      if (opcode != other.opcode) @@ -247,7 +246,6 @@ GVN::Expression GVN::ValueTable::createExpr(Instruction *I) {      assert(I->getNumOperands() == 2 && "Unsupported commutative instruction!");      if (e.varargs[0] > e.varargs[1])        std::swap(e.varargs[0], e.varargs[1]); -    e.commutative = true;    }    if (CmpInst *C = dyn_cast<CmpInst>(I)) { @@ -258,7 +256,6 @@ GVN::Expression GVN::ValueTable::createExpr(Instruction *I) {        Predicate = CmpInst::getSwappedPredicate(Predicate);      }      e.opcode = (C->getOpcode() << 8) | Predicate; -    e.commutative = true;    } else if (InsertValueInst *E = dyn_cast<InsertValueInst>(I)) {      for (InsertValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end();           II != IE; ++II) @@ -284,7 +281,6 @@ GVN::Expression GVN::ValueTable::createCmpExpr(unsigned Opcode,      Predicate = CmpInst::getSwappedPredicate(Predicate);    }    e.opcode = (Opcode << 8) | Predicate; -  e.commutative = true;    return e;  } @@ -352,25 +348,25 @@ GVN::ValueTable::~ValueTable() = default;  /// add - Insert a value into the table with a specified value number.  void GVN::ValueTable::add(Value *V, uint32_t num) {    valueNumbering.insert(std::make_pair(V, num)); -  if (PHINode *PN = dyn_cast<PHINode>(V)) -    NumberingPhi[num] = PN;  }  uint32_t GVN::ValueTable::lookupOrAddCall(CallInst *C) {    if (AA->doesNotAccessMemory(C)) {      Expression exp = createExpr(C); -    uint32_t e = assignExpNewValueNum(exp).first; +    uint32_t &e = expressionNumbering[exp]; +    if (!e) e = nextValueNumber++;      valueNumbering[C] = e;      return e;    } else if (AA->onlyReadsMemory(C)) {      Expression exp = createExpr(C); -    auto ValNum = assignExpNewValueNum(exp); -    if (ValNum.second) { -      valueNumbering[C] = ValNum.first; -      return ValNum.first; +    uint32_t &e = expressionNumbering[exp]; +    if (!e) { +      e = nextValueNumber++; +      valueNumbering[C] = e; +      return e;      }      if (!MD) { -      uint32_t e = assignExpNewValueNum(exp).first; +      e = nextValueNumber++;        valueNumbering[C] = e;        return e;      } @@ -526,29 +522,23 @@ uint32_t GVN::ValueTable::lookupOrAdd(Value *V) {      case Instruction::ExtractValue:        exp = createExtractvalueExpr(cast<ExtractValueInst>(I));        break; -    case Instruction::PHI: -      valueNumbering[V] = nextValueNumber; -      NumberingPhi[nextValueNumber] = cast<PHINode>(V); -      return nextValueNumber++;      default:        valueNumbering[V] = nextValueNumber;        return nextValueNumber++;    } -  uint32_t e = assignExpNewValueNum(exp).first; +  uint32_t& e = expressionNumbering[exp]; +  if (!e) e = nextValueNumber++;    valueNumbering[V] = e;    return e;  }  /// Returns the value number of the specified value. Fails if  /// the value has not yet been numbered. -uint32_t GVN::ValueTable::lookup(Value *V, bool Verify) const { +uint32_t GVN::ValueTable::lookup(Value *V) const {    DenseMap<Value*, uint32_t>::const_iterator VI = valueNumbering.find(V); -  if (Verify) { -    assert(VI != valueNumbering.end() && "Value not numbered?"); -    return VI->second; -  } -  return (VI != valueNumbering.end()) ? VI->second : 0; +  assert(VI != valueNumbering.end() && "Value not numbered?"); +  return VI->second;  }  /// Returns the value number of the given comparison, @@ -559,29 +549,21 @@ uint32_t GVN::ValueTable::lookupOrAddCmp(unsigned Opcode,                                           CmpInst::Predicate Predicate,                                           Value *LHS, Value *RHS) {    Expression exp = createCmpExpr(Opcode, Predicate, LHS, RHS); -  return assignExpNewValueNum(exp).first; +  uint32_t& e = expressionNumbering[exp]; +  if (!e) e = nextValueNumber++; +  return e;  }  /// Remove all entries from the ValueTable.  void GVN::ValueTable::clear() {    valueNumbering.clear();    expressionNumbering.clear(); -  NumberingPhi.clear(); -  PhiTranslateTable.clear(); -  BlockRPONumber.clear();    nextValueNumber = 1; -  Expressions.clear(); -  ExprIdx.clear(); -  nextExprNumber = 0;  }  /// Remove a value from the value numbering.  void GVN::ValueTable::erase(Value *V) { -  uint32_t Num = valueNumbering.lookup(V);    valueNumbering.erase(V); -  // If V is PHINode, V <--> value number is an one-to-one mapping. -  if (isa<PHINode>(V)) -    NumberingPhi.erase(Num);  }  /// verifyRemoved - Verify that the value is removed from all internal data @@ -1469,104 +1451,6 @@ bool GVN::processLoad(LoadInst *L) {    return false;  } -/// Return a pair the first field showing the value number of \p Exp and the -/// second field showing whether it is a value number newly created. -std::pair<uint32_t, bool> -GVN::ValueTable::assignExpNewValueNum(Expression &Exp) { -  uint32_t &e = expressionNumbering[Exp]; -  bool CreateNewValNum = !e; -  if (CreateNewValNum) { -    Expressions.push_back(Exp); -    if (ExprIdx.size() < nextValueNumber + 1) -      ExprIdx.resize(nextValueNumber * 2); -    e = nextValueNumber; -    ExprIdx[nextValueNumber++] = nextExprNumber++; -  } -  return {e, CreateNewValNum}; -} - -void GVN::ValueTable::assignBlockRPONumber(Function &F) { -  uint32_t NextBlockNumber = 1; -  ReversePostOrderTraversal<Function *> RPOT(&F); -  for (BasicBlock *BB : RPOT) -    BlockRPONumber[BB] = NextBlockNumber++; -} - -/// Return whether all the values related with the same \p num are -/// defined in \p BB. -bool GVN::ValueTable::areAllValsInBB(uint32_t Num, const BasicBlock *BB, -                                     GVN &Gvn) { -  LeaderTableEntry *Vals = &Gvn.LeaderTable[Num]; -  while (Vals && Vals->BB == BB) -    Vals = Vals->Next; -  return !Vals; -} - -/// Wrap phiTranslateImpl to provide caching functionality. -uint32_t GVN::ValueTable::phiTranslate(const BasicBlock *Pred, -                                       const BasicBlock *PhiBlock, uint32_t Num, -                                       GVN &Gvn) { -  auto FindRes = PhiTranslateTable.find({Num, Pred}); -  if (FindRes != PhiTranslateTable.end()) -    return FindRes->second; -  uint32_t NewNum = phiTranslateImpl(Pred, PhiBlock, Num, Gvn); -  PhiTranslateTable.insert({{Num, Pred}, NewNum}); -  return NewNum; -} - -/// Translate value number \p Num using phis, so that it has the values of -/// the phis in BB. -uint32_t GVN::ValueTable::phiTranslateImpl(const BasicBlock *Pred, -                                           const BasicBlock *PhiBlock, -                                           uint32_t Num, GVN &Gvn) { -  if (PHINode *PN = NumberingPhi[Num]) { -    if (BlockRPONumber[Pred] >= BlockRPONumber[PhiBlock]) -      return Num; -    for (unsigned i = 0; i != PN->getNumIncomingValues(); ++i) { -      if (PN->getParent() == PhiBlock && PN->getIncomingBlock(i) == Pred) -        if (uint32_t TransVal = lookup(PN->getIncomingValue(i), false)) -          return TransVal; -    } -    return Num; -  } - -  // If there is any value related with Num is defined in a BB other than -  // PhiBlock, it cannot depend on a phi in PhiBlock without going through -  // a backedge. We can do an early exit in that case to save compile time. -  if (!areAllValsInBB(Num, PhiBlock, Gvn)) -    return Num; - -  if (ExprIdx[Num] == 0 || Num >= ExprIdx.size()) -    return Num; -  Expression Exp = Expressions[ExprIdx[Num]]; - -  for (unsigned i = 0; i < Exp.varargs.size(); i++) { -    // For InsertValue and ExtractValue, some varargs are index numbers -    // instead of value numbers. Those index numbers should not be -    // translated. -    if ((i > 1 && Exp.opcode == Instruction::InsertValue) || -        (i > 0 && Exp.opcode == Instruction::ExtractValue)) -      continue; -    Exp.varargs[i] = phiTranslate(Pred, PhiBlock, Exp.varargs[i], Gvn); -  } - -  if (Exp.commutative) { -    assert(Exp.varargs.size() == 2 && "Unsupported commutative expression!"); -    if (Exp.varargs[0] > Exp.varargs[1]) { -      std::swap(Exp.varargs[0], Exp.varargs[1]); -      uint32_t Opcode = Exp.opcode >> 8; -      if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) -        Exp.opcode = (Opcode << 8) | -                     CmpInst::getSwappedPredicate( -                         static_cast<CmpInst::Predicate>(Exp.opcode & 255)); -    } -  } - -  if (uint32_t NewNum = expressionNumbering[Exp]) -    return NewNum; -  return Num; -} -  // In order to find a leader for a given value number at a  // specific basic block, we first obtain the list of all Values for that number,  // and then scan the list to find one whose block dominates the block in @@ -1972,7 +1856,6 @@ bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,      // Fabricate val-num for dead-code in order to suppress assertion in      // performPRE().      assignValNumForDeadCode(); -    VN.assignBlockRPONumber(F);      bool PREChanged = true;      while (PREChanged) {        PREChanged = performPRE(F); @@ -2062,9 +1945,7 @@ bool GVN::performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,        success = false;        break;      } -    uint32_t TValNo = -        VN.phiTranslate(Pred, Instr->getParent(), VN.lookup(Op), *this); -    if (Value *V = findLeader(Pred, TValNo)) { +    if (Value *V = findLeader(Pred, VN.lookup(Op))) {        Instr->setOperand(i, V);      } else {        success = false; @@ -2081,12 +1962,10 @@ bool GVN::performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,    Instr->insertBefore(Pred->getTerminator());    Instr->setName(Instr->getName() + ".pre");    Instr->setDebugLoc(Instr->getDebugLoc()); - -  unsigned Num = VN.lookupOrAdd(Instr); -  VN.add(Instr, Num); +  VN.add(Instr, ValNo);    // Update the availability map to include the new instruction. -  addToLeaderTable(Num, Instr, Pred); +  addToLeaderTable(ValNo, Instr, Pred);    return true;  } @@ -2135,8 +2014,7 @@ bool GVN::performScalarPRE(Instruction *CurInst) {        break;      } -    uint32_t TValNo = VN.phiTranslate(P, CurrentBlock, ValNo, *this); -    Value *predV = findLeader(P, TValNo); +    Value *predV = findLeader(P, ValNo);      if (!predV) {        predMap.push_back(std::make_pair(static_cast<Value *>(nullptr), P));        PREPred = P; diff --git a/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp b/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp index a143b9a3c645..930696b036c0 100644 --- a/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp +++ b/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp @@ -98,11 +98,20 @@ template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {    CallInst *CI;    ICmpInst *CmpI = dyn_cast<ICmpInst>(BSI.getCondition()); +  CmpInst::Predicate Predicate; +  uint64_t ValueComparedTo = 0;    if (!CmpI) {      CI = dyn_cast<CallInst>(BSI.getCondition()); +    Predicate = CmpInst::ICMP_NE; +    ValueComparedTo = 0;    } else { -    if (CmpI->getPredicate() != CmpInst::ICMP_NE) +    Predicate = CmpI->getPredicate(); +    if (Predicate != CmpInst::ICMP_NE && Predicate != CmpInst::ICMP_EQ)        return false; +    ConstantInt *CmpConstOperand = dyn_cast<ConstantInt>(CmpI->getOperand(1)); +    if (!CmpConstOperand) +      return false; +    ValueComparedTo = CmpConstOperand->getZExtValue();      CI = dyn_cast<CallInst>(CmpI->getOperand(0));    } @@ -121,9 +130,8 @@ template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {    MDBuilder MDB(CI->getContext());    MDNode *Node; -  // If expect value is equal to 1 it means that we are more likely to take -  // branch 0, in other case more likely is branch 1. -  if (ExpectedValue->isOne()) +  if ((ExpectedValue->getZExtValue() == ValueComparedTo) == +      (Predicate == CmpInst::ICMP_EQ))      Node = MDB.createBranchWeights(LikelyBranchWeight, UnlikelyBranchWeight);    else      Node = MDB.createBranchWeights(UnlikelyBranchWeight, LikelyBranchWeight); diff --git a/lib/Transforms/Scalar/NewGVN.cpp b/lib/Transforms/Scalar/NewGVN.cpp index 5e9f40019ce8..27809f5b6f66 100644 --- a/lib/Transforms/Scalar/NewGVN.cpp +++ b/lib/Transforms/Scalar/NewGVN.cpp @@ -613,7 +613,7 @@ private:      return CClass;    }    void initializeCongruenceClasses(Function &F); -  const Expression *makePossiblePhiOfOps(Instruction *, bool, +  const Expression *makePossiblePhiOfOps(Instruction *,                                           SmallPtrSetImpl<Value *> &);    void addPhiOfOps(PHINode *Op, BasicBlock *BB, Instruction *ExistingValue); @@ -1937,7 +1937,8 @@ void NewGVN::touchAndErase(Map &M, const KeyType &Key) {  }  void NewGVN::addAdditionalUsers(Value *To, Value *User) const { -  AdditionalUsers[To].insert(User); +  if (isa<Instruction>(To)) +    AdditionalUsers[To].insert(User);  }  void NewGVN::markUsersTouched(Value *V) { @@ -2423,7 +2424,7 @@ static bool okayForPHIOfOps(const Instruction *I) {  // When we see an instruction that is an op of phis, generate the equivalent phi  // of ops form.  const Expression * -NewGVN::makePossiblePhiOfOps(Instruction *I, bool HasBackedge, +NewGVN::makePossiblePhiOfOps(Instruction *I,                               SmallPtrSetImpl<Value *> &Visited) {    if (!okayForPHIOfOps(I))      return nullptr; @@ -2438,24 +2439,6 @@ NewGVN::makePossiblePhiOfOps(Instruction *I, bool HasBackedge,      return nullptr;    unsigned IDFSNum = InstrToDFSNum(I); -  // Pretty much all of the instructions we can convert to phi of ops over a -  // backedge that are adds, are really induction variables, and those are -  // pretty much pointless to convert.  This is very coarse-grained for a -  // test, so if we do find some value, we can change it later. -  // But otherwise, what can happen is we convert the induction variable from -  // -  // i = phi (0, tmp) -  // tmp = i + 1 -  // -  // to -  // i = phi (0, tmpphi) -  // tmpphi = phi(1, tmpphi+1) -  // -  // Which we don't want to happen.  We could just avoid this for all non-cycle -  // free phis, and we made go that route. -  if (HasBackedge && I->getOpcode() == Instruction::Add) -    return nullptr; -    SmallPtrSet<const Value *, 8> ProcessedPHIs;    // TODO: We don't do phi translation on memory accesses because it's    // complicated. For a load, we'd need to be able to simulate a new memoryuse, @@ -2470,6 +2453,16 @@ NewGVN::makePossiblePhiOfOps(Instruction *I, bool HasBackedge,    // Convert op of phis to phi of ops    for (auto &Op : I->operands()) { +    // TODO: We can't handle expressions that must be recursively translated +    // IE +    // a = phi (b, c) +    // f = use a +    // g = f + phi of something +    // To properly make a phi of ops for g, we'd have to properly translate and +    // use the instruction for f.  We should add this by splitting out the +    // instruction creation we do below. +    if (isa<Instruction>(Op) && PHINodeUses.count(cast<Instruction>(Op))) +      return nullptr;      if (!isa<PHINode>(Op))        continue;      auto *OpPHI = cast<PHINode>(Op); @@ -2782,8 +2775,7 @@ void NewGVN::valueNumberInstruction(Instruction *I) {        // Make a phi of ops if necessary        if (Symbolized && !isa<ConstantExpression>(Symbolized) &&            !isa<VariableExpression>(Symbolized) && PHINodeUses.count(I)) { -        // FIXME: Backedge argument -        auto *PHIE = makePossiblePhiOfOps(I, false, Visited); +        auto *PHIE = makePossiblePhiOfOps(I, Visited);          if (PHIE)            Symbolized = PHIE;        }  | 
