Esempio n. 1
0
void TestInstVisitor::visitSwitchInst(SwitchInst &I){
    if (except){
        return;
    }

    DynValEntry entry;
    size_t n = fread(&entry, sizeof(DynValEntry), 1, dlog);
    if (entry.entrytype == EXCEPTIONENTRY){
        except = true;
        return;
    }
    assert(entry.entrytype == SWITCHENTRY);
    //printf("switch %d\n", entry.entry.switchstmt.cond);
    IntegerType *intType = IntegerType::get(getGlobalContext(), sizeof(int)*8);
    ConstantInt *caseVal =
        ConstantInt::get(intType, entry.entry.switchstmt.cond);
    SwitchInst::CaseIt caseIndex = I.findCaseValue(caseVal);
    TFP->setNextBB(I.getSuccessor(caseIndex.getSuccessorIndex()));
}
Esempio n. 2
0
// RewriteLoopBodyWithConditionConstant - We know either that the value LIC has
// the value specified by Val in the specified loop, or we know it does NOT have
// that value.  Rewrite any uses of LIC or of properties correlated to it.
void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
                                                        Constant *Val,
                                                        bool IsEqual) {
  assert(!isa<Constant>(LIC) && "Why are we unswitching on a constant?");
  
  // FIXME: Support correlated properties, like:
  //  for (...)
  //    if (li1 < li2)
  //      ...
  //    if (li1 > li2)
  //      ...
  
  // FOLD boolean conditions (X|LIC), (X&LIC).  Fold conditional branches,
  // selects, switches.
  std::vector<User*> Users(LIC->use_begin(), LIC->use_end());
  std::vector<Instruction*> Worklist;
  LLVMContext &Context = Val->getContext();


  // If we know that LIC == Val, or that LIC == NotVal, just replace uses of LIC
  // in the loop with the appropriate one directly.
  if (IsEqual || (isa<ConstantInt>(Val) &&
      Val->getType()->isIntegerTy(1))) {
    Value *Replacement;
    if (IsEqual)
      Replacement = Val;
    else
      Replacement = ConstantInt::get(Type::getInt1Ty(Val->getContext()), 
                                     !cast<ConstantInt>(Val)->getZExtValue());
    
    for (unsigned i = 0, e = Users.size(); i != e; ++i)
      if (Instruction *U = cast<Instruction>(Users[i])) {
        if (!L->contains(U))
          continue;
        U->replaceUsesOfWith(LIC, Replacement);
        Worklist.push_back(U);
      }
    SimplifyCode(Worklist, L);
    return;
  }
  
  // Otherwise, we don't know the precise value of LIC, but we do know that it
  // is certainly NOT "Val".  As such, simplify any uses in the loop that we
  // can.  This case occurs when we unswitch switch statements.
  for (unsigned i = 0, e = Users.size(); i != e; ++i) {
    Instruction *U = cast<Instruction>(Users[i]);
    if (!L->contains(U))
      continue;

    Worklist.push_back(U);

    // TODO: We could do other simplifications, for example, turning 
    // 'icmp eq LIC, Val' -> false.

    // If we know that LIC is not Val, use this info to simplify code.
    SwitchInst *SI = dyn_cast<SwitchInst>(U);
    if (SI == 0 || !isa<ConstantInt>(Val)) continue;
    
    unsigned DeadCase = SI->findCaseValue(cast<ConstantInt>(Val));
    if (DeadCase == 0) continue;  // Default case is live for multiple values.
    
    // Found a dead case value.  Don't remove PHI nodes in the 
    // successor if they become single-entry, those PHI nodes may
    // be in the Users list.
        
    // FIXME: This is a hack.  We need to keep the successor around
    // and hooked up so as to preserve the loop structure, because
    // trying to update it is complicated.  So instead we preserve the
    // loop structure and put the block on a dead code path.
    BasicBlock *Switch = SI->getParent();
    SplitEdge(Switch, SI->getSuccessor(DeadCase), this);
    // Compute the successors instead of relying on the return value
    // of SplitEdge, since it may have split the switch successor
    // after PHI nodes.
    BasicBlock *NewSISucc = SI->getSuccessor(DeadCase);
    BasicBlock *OldSISucc = *succ_begin(NewSISucc);
    // Create an "unreachable" destination.
    BasicBlock *Abort = BasicBlock::Create(Context, "us-unreachable",
                                           Switch->getParent(),
                                           OldSISucc);
    new UnreachableInst(Context, Abort);
    // Force the new case destination to branch to the "unreachable"
    // block while maintaining a (dead) CFG edge to the old block.
    NewSISucc->getTerminator()->eraseFromParent();
    BranchInst::Create(Abort, OldSISucc,
                       ConstantInt::getTrue(Context), NewSISucc);
    // Release the PHI operands for this edge.
    for (BasicBlock::iterator II = NewSISucc->begin();
         PHINode *PN = dyn_cast<PHINode>(II); ++II)
      PN->setIncomingValue(PN->getBasicBlockIndex(Switch),
                           UndefValue::get(PN->getType()));
    // Tell the domtree about the new block. We don't fully update the
    // domtree here -- instead we force it to do a full recomputation
    // after the pass is complete -- but we do need to inform it of
    // new blocks.
    if (DT)
      DT->addNewBlock(Abort, NewSISucc);
  }
  
  SimplifyCode(Worklist, L);
}
Esempio n. 3
0
// Set outgoing edges alive dependent on the terminator instruction SI.
// If the terminator is an Invoke instruction, the call has already been run.
// Return true if anything changed.
bool IntegrationAttempt::checkBlockOutgoingEdges(ShadowInstruction* SI) {

  // TOCHECK: I think this only returns false if the block ends with an Unreachable inst?
  switch(SI->invar->I->getOpcode()) {
  case Instruction::Br:
  case Instruction::Switch:
  case Instruction::Invoke:
  case Instruction::Resume:
    break;
  default:
    return false;
  }

  if(inst_is<InvokeInst>(SI)) {

    InlineAttempt* IA = getInlineAttempt(SI);

    bool changed = false;

    // !localStore indicates the invoke instruction doesn't return normally
    if(SI->parent->localStore) {

      changed |= !SI->parent->succsAlive[0];
      SI->parent->succsAlive[0] = true;

    }      

    // I mark the exceptional edge reachable here if the call is disabled, even though
    // we might have proved it isn't feasible. This could be improved by converting the
    // invoke into a call in the final program.
    if((!IA) || (!IA->isEnabled()) || IA->mayUnwind) {

      changed |= !SI->parent->succsAlive[1];
      SI->parent->succsAlive[1] = true;

    }

    return changed;
    
  }
  else if(inst_is<ResumeInst>(SI)) {

    bool changed = !mayUnwind;
    mayUnwind = true;
    return changed;

  }
  else if(BranchInst* BI = dyn_cast_inst<BranchInst>(SI)) {

    if(BI->isUnconditional()) {
      bool changed = !SI->parent->succsAlive[0];
      SI->parent->succsAlive[0] = true;
      return changed;
    }

  }

  // Both switches and conditional branches use operand 0 for the condition.
  ShadowValue Condition = SI->getOperand(0);
      
  bool changed = false;
  
  ConstantInt* ConstCondition = dyn_cast_or_null<ConstantInt>(getConstReplacement(Condition));
  if(!ConstCondition) {

    if(Condition.t == SHADOWVAL_INST || Condition.t == SHADOWVAL_ARG) {

      // Switch statements can operate on a ptrtoint operand, of which only ptrtoint(null) is useful:
      if(ImprovedValSetSingle* IVS = dyn_cast_or_null<ImprovedValSetSingle>(getIVSRef(Condition))) {
	
	if(IVS->onlyContainsNulls()) {
	  
	  ConstCondition = cast<ConstantInt>(Constant::getNullValue(SI->invar->I->getOperand(0)->getType()));
	  
	}

      }

    }

  }

  if(!ConstCondition) {
    
    std::pair<ValSetType, ImprovedVal> PathVal;

    if(tryGetPathValue(Condition, SI->parent, PathVal))
      ConstCondition = dyn_cast_val<ConstantInt>(PathVal.second.V);

  }

  TerminatorInst* TI = cast_inst<TerminatorInst>(SI);
  const unsigned NumSucc = TI->getNumSuccessors();

  if(ConstCondition) {

    BasicBlock* takenTarget = 0;

    if(BranchInst* BI = dyn_cast_inst<BranchInst>(SI)) {
      // This ought to be a boolean.
      if(ConstCondition->isZero())
	takenTarget = BI->getSuccessor(1);
      else
	takenTarget = BI->getSuccessor(0);
    }
    else {
      SwitchInst* SwI = cast_inst<SwitchInst>(SI);
      SwitchInst::CaseIt targetidx = SwI->findCaseValue(ConstCondition);
      takenTarget = targetidx.getCaseSuccessor();
    }
    if(takenTarget) {
      // We know where the instruction is going -- remove this block as a predecessor for its other targets.
      LPDEBUG("Branch or switch instruction given known target: " << takenTarget->getName() << "\n");

      return setEdgeAlive(TI, SI->parent, takenTarget);

    }
    
    // Else fall through to set all alive.

  }

  SwitchInst* Switch;
  ImprovedValSetSingle* IVS;

  if((Switch = dyn_cast_inst<SwitchInst>(SI)) && 
     (IVS = dyn_cast<ImprovedValSetSingle>(getIVSRef(Condition))) && 
     IVS->SetType == ValSetTypeScalar && 
     !IVS->Values.empty()) {

    // A set of values feeding a switch. Set each corresponding edge alive.

    bool changed = false;

    for (unsigned i = 0, ilim = IVS->Values.size(); i != ilim; ++i) {
      
      SwitchInst::CaseIt targetit = Switch->findCaseValue(cast<ConstantInt>(getConstReplacement(IVS->Values[i].V)));
      BasicBlock* target = targetit.getCaseSuccessor();
      changed |= setEdgeAlive(TI, SI->parent, target);

    }

    return changed;

  }

  // Condition unknown -- set all successors alive.
  for (unsigned I = 0; I != NumSucc; ++I) {
    
    // Mark outgoing edge alive
    if(!SI->parent->succsAlive[I])
      changed = true;
    SI->parent->succsAlive[I] = true;
    
  }

  return changed;

}