Ejemplo n.º 1
0
Archivo: ABCD.cpp Proyecto: aaasz/SHP
/// Iterates through all BasicBlocks, if the Terminator Instruction
/// uses an Comparator Instruction, all operands of this comparator
/// are sent to be transformed to SSI. Only Instruction operands are
/// transformed.
void ABCD::createSSI(Function &F) {
  SSI *ssi = &getAnalysis<SSI>();

  SmallVector<Instruction *, 16> Insts;

  for (Function::iterator begin = F.begin(), end = F.end();
       begin != end; ++begin) {
    BasicBlock *BB = begin;
    TerminatorInst *TI = BB->getTerminator();
    if (TI->getNumOperands() == 0)
      continue;

    if (ICmpInst *ICI = dyn_cast<ICmpInst>(TI->getOperand(0))) {
      if (Instruction *I = dyn_cast<Instruction>(ICI->getOperand(0))) {
        modified = true;  // XXX: but yet createSSI might do nothing
        Insts.push_back(I);
      }
      if (Instruction *I = dyn_cast<Instruction>(ICI->getOperand(1))) {
        modified = true;
        Insts.push_back(I);
      }
    }
  }
  ssi->createSSI(Insts);
}
Ejemplo n.º 2
0
Archivo: ABCD.cpp Proyecto: aaasz/SHP
/// Creates the graphs for this function.
/// It will look for all comparators used in branches, and create them.
/// These comparators will create constraints for any instruction as an
/// operand.
void ABCD::executeABCD(Function &F) {
  for (Function::iterator begin = F.begin(), end = F.end();
       begin != end; ++begin) {
    BasicBlock *BB = begin;
    TerminatorInst *TI = BB->getTerminator();
    if (TI->getNumOperands() == 0)
      continue;

    ICmpInst *ICI = dyn_cast<ICmpInst>(TI->getOperand(0));
    if (!ICI || !isa<IntegerType>(ICI->getOperand(0)->getType()))
      continue;

    createConstraintCmpInst(ICI, TI);
    seekRedundancy(ICI, TI);
  }
}
Ejemplo n.º 3
0
bool ScopDetection::isValidCFG(BasicBlock &BB,
                               DetectionContext &Context) const {
  Region &RefRegion = Context.CurRegion;
  TerminatorInst *TI = BB.getTerminator();

  // Return instructions are only valid if the region is the top level region.
  if (isa<ReturnInst>(TI) && !RefRegion.getExit() && TI->getNumOperands() == 0)
    return true;

  BranchInst *Br = dyn_cast<BranchInst>(TI);

  if (!Br)
    return invalid<ReportNonBranchTerminator>(Context, /*Assert=*/true, &BB);

  if (Br->isUnconditional())
    return true;

  Value *Condition = Br->getCondition();

  // UndefValue is not allowed as condition.
  if (isa<UndefValue>(Condition))
    return invalid<ReportUndefCond>(Context, /*Assert=*/true, &BB);

  // Only Constant and ICmpInst are allowed as condition.
  if (!(isa<Constant>(Condition) || isa<ICmpInst>(Condition)))
    return invalid<ReportInvalidCond>(Context, /*Assert=*/true, &BB);

  // Allow perfectly nested conditions.
  assert(Br->getNumSuccessors() == 2 && "Unexpected number of successors");

  if (ICmpInst *ICmp = dyn_cast<ICmpInst>(Condition)) {
    // Unsigned comparisons are not allowed. They trigger overflow problems
    // in the code generation.
    //
    // TODO: This is not sufficient and just hides bugs. However it does pretty
    // well.
    if (ICmp->isUnsigned())
      return false;

    // Are both operands of the ICmp affine?
    if (isa<UndefValue>(ICmp->getOperand(0)) ||
        isa<UndefValue>(ICmp->getOperand(1)))
      return invalid<ReportUndefOperand>(Context, /*Assert=*/true, &BB);

    Loop *L = LI->getLoopFor(ICmp->getParent());
    const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L);
    const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L);

    if (!isAffineExpr(&Context.CurRegion, LHS, *SE) ||
        !isAffineExpr(&Context.CurRegion, RHS, *SE))
      return invalid<ReportNonAffBranch>(Context, /*Assert=*/true, &BB, LHS,
                                         RHS);
  }

  // Allow loop exit conditions.
  Loop *L = LI->getLoopFor(&BB);
  if (L && L->getExitingBlock() == &BB)
    return true;

  // Allow perfectly nested conditions.
  Region *R = RI->getRegionFor(&BB);
  if (R->getEntry() != &BB)
    return invalid<ReportCondition>(Context, /*Assert=*/true, &BB);

  return true;
}