Example #1
0
//
// For a given BasicBlock, compute which variables are defined.
//
Assignments DataFlowUtil::defines(const BasicBlock& block) {
  Assignments defSet;
  for (BasicBlock::const_iterator it = block.begin(); it != block.end(); ++it) {
    // there's no result area for an instr, every instruction is actually a definition
    const Instruction& instr = *it;
    defSet.insert(Assignment(&instr));
  }
  return defSet;
}
Example #2
0
void DataFlowUtil::setIntersect(Assignments& dest, const Assignments& src) {
  Assignments result;
  for (Assignments::const_iterator i = src.begin(); i != src.end(); ++i) {
    const Assignment& test = *i;
    if (src.count(test) > 0 && dest.count(test) > 0) {
      result.insert(test);
    }
  }
  // rewrite the destination
  dest = result;
}
Example #3
0
Assignments DataFlowUtil::all(const Function& fn) {
  Assignments all;

  // Function arguments are values too.
  for (Function::const_arg_iterator I = fn.arg_begin(), IE = fn.arg_end();
      I != IE; ++I) {
    const Argument* arg = &(*I);
    Assignment assign(arg);
    all.insert(assign);
  }

  // Populate with all instructions.
  // TODO: What do we do with loads and stores? Treat the same for now.
  for (Function::const_iterator I = fn.begin(), IE = fn.end(); I != IE; ++I) {
    const BasicBlock& block = *I;
    for (BasicBlock::const_iterator J = block.begin(), JE = block.end();
        J != JE; ++J) {
      const Instruction* instr = &(*J);
      Assignment assign(instr);
      all.insert(assign);
    }
  }
  return all;
}
Example #4
0
//
// For a given BasicBlock, compute which variables are used.
//
Assignments DataFlowUtil::uses(const BasicBlock& block) {
  Assignments useSet;
  for (BasicBlock::const_reverse_iterator it = block.rbegin(); it != block.rend(); ++it) {
    const Instruction& instr = *it;
    const User* user = &instr;
    // iterate through all operands
    User::const_op_iterator OI, OE;
    for(OI = user->op_begin(), OE = user->op_end(); OI != OE; ++OI) {
      Value* val = *OI;
      // check if the operand is used
      if ((isa<Instruction>(val) || isa<Argument>(val)) && (!isa<PHINode>(val))) {
        useSet.insert(Assignment(val));
      }
    }
    useSet.erase(Assignment(&instr));
  }
  return useSet;
}
Example #5
0
Assignments DataFlowUtil::kills(const BasicBlock& block) {
  Assignments killSet;
  const Function& function = *block.getParent();
  for (BasicBlock::const_iterator it = block.begin(); it != block.end(); ++it) {
    const Instruction& inst = *it;

    for(Function::const_iterator itrF = function.begin(); itrF != function.end(); ++itrF) {
      const BasicBlock& bb = *itrF;
      if (&bb == &block) {
        for(BasicBlock::const_iterator itrB = bb.begin(); itrB != bb.end(); ++itrB) {
          const Instruction& instr = *itrB;
          if (&inst == &instr) {
            killSet.insert(Assignment(&instr));
          }
        }
      }
    }
  }
  return killSet;
}
Example #6
0
void DataFlowUtil::setUnion(Assignments& dest, const Assignments& src) {
  for (Assignments::const_iterator i = src.begin(); i != src.end(); ++i) {
    const Assignment& add = *i;
    dest.insert(add);
  }
}