本文整理汇总了C++中BinaryOperator::setOperand方法的典型用法代码示例。如果您正苦于以下问题:C++ BinaryOperator::setOperand方法的具体用法?C++ BinaryOperator::setOperand怎么用?C++ BinaryOperator::setOperand使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BinaryOperator
的用法示例。
在下文中一共展示了BinaryOperator::setOperand方法的5个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: LinearizeExpr
// Given an expression of the form '(A+B)+(D+C)', turn it into '(((A+B)+C)+D)'.
// Note that if D is also part of the expression tree that we recurse to
// linearize it as well. Besides that case, this does not recurse into A,B, or
// C.
void Reassociate::LinearizeExpr(BinaryOperator *I) {
BinaryOperator *LHS = cast<BinaryOperator>(I->getOperand(0));
BinaryOperator *RHS = cast<BinaryOperator>(I->getOperand(1));
assert(isReassociableOp(LHS, I->getOpcode()) &&
isReassociableOp(RHS, I->getOpcode()) &&
"Not an expression that needs linearization?");
DEBUG(dbgs() << "Linear" << *LHS << '\n' << *RHS << '\n' << *I << '\n');
// Move the RHS instruction to live immediately before I, avoiding breaking
// dominator properties.
RHS->moveBefore(I);
// Move operands around to do the linearization.
I->setOperand(1, RHS->getOperand(0));
RHS->setOperand(0, LHS);
I->setOperand(0, RHS);
// Conservatively clear all the optional flags, which may not hold
// after the reassociation.
I->clearSubclassOptionalData();
LHS->clearSubclassOptionalData();
RHS->clearSubclassOptionalData();
++NumLinear;
MadeChange = true;
DEBUG(dbgs() << "Linearized: " << *I << '\n');
// If D is part of this expression tree, tail recurse.
if (isReassociableOp(I->getOperand(1), I->getOpcode()))
LinearizeExpr(I);
}
示例2: getNullValue
Value *ConstantOffsetExtractor::removeConstOffset(unsigned ChainIndex) {
if (ChainIndex == 0) {
assert(isa<ConstantInt>(UserChain[ChainIndex]));
return ConstantInt::getNullValue(UserChain[ChainIndex]->getType());
}
BinaryOperator *BO = cast<BinaryOperator>(UserChain[ChainIndex]);
unsigned OpNo = (BO->getOperand(0) == UserChain[ChainIndex - 1] ? 0 : 1);
assert(BO->getOperand(OpNo) == UserChain[ChainIndex - 1]);
Value *NextInChain = removeConstOffset(ChainIndex - 1);
Value *TheOther = BO->getOperand(1 - OpNo);
// If NextInChain is 0 and not the LHS of a sub, we can simplify the
// sub-expression to be just TheOther.
if (ConstantInt *CI = dyn_cast<ConstantInt>(NextInChain)) {
if (CI->isZero() && !(BO->getOpcode() == Instruction::Sub && OpNo == 0))
return TheOther;
}
if (BO->getOpcode() == Instruction::Or) {
// Rebuild "or" as "add", because "or" may be invalid for the new
// epxression.
//
// For instance, given
// a | (b + 5) where a and b + 5 have no common bits,
// we can extract 5 as the constant offset.
//
// However, reusing the "or" in the new index would give us
// (a | b) + 5
// which does not equal a | (b + 5).
//
// Replacing the "or" with "add" is fine, because
// a | (b + 5) = a + (b + 5) = (a + b) + 5
if (OpNo == 0) {
return BinaryOperator::CreateAdd(NextInChain, TheOther, BO->getName(),
IP);
} else {
return BinaryOperator::CreateAdd(TheOther, NextInChain, BO->getName(),
IP);
}
}
// We can reuse BO in this case, because the new expression shares the same
// instruction type and BO is used at most once.
assert(BO->getNumUses() <= 1 &&
"distributeExtsAndCloneChain clones each BinaryOperator in "
"UserChain, so no one should be used more than "
"once");
BO->setOperand(OpNo, NextInChain);
BO->setHasNoSignedWrap(false);
BO->setHasNoUnsignedWrap(false);
// Make sure it appears after all instructions we've inserted so far.
BO->moveBefore(IP);
return BO;
}
示例3: SimplifyDivRemOfSelect
/// SimplifyDivRemOfSelect - Try to fold a divide or remainder of a select
/// instruction.
bool InstCombiner::SimplifyDivRemOfSelect(BinaryOperator &I) {
SelectInst *SI = cast<SelectInst>(I.getOperand(1));
// div/rem X, (Cond ? 0 : Y) -> div/rem X, Y
int NonNullOperand = -1;
if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1)))
if (ST->isNullValue())
NonNullOperand = 2;
// div/rem X, (Cond ? Y : 0) -> div/rem X, Y
if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2)))
if (ST->isNullValue())
NonNullOperand = 1;
if (NonNullOperand == -1)
return false;
Value *SelectCond = SI->getOperand(0);
// Change the div/rem to use 'Y' instead of the select.
I.setOperand(1, SI->getOperand(NonNullOperand));
// Okay, we know we replace the operand of the div/rem with 'Y' with no
// problem. However, the select, or the condition of the select may have
// multiple uses. Based on our knowledge that the operand must be non-zero,
// propagate the known value for the select into other uses of it, and
// propagate a known value of the condition into its other users.
// If the select and condition only have a single use, don't bother with this,
// early exit.
if (SI->use_empty() && SelectCond->hasOneUse())
return true;
// Scan the current block backward, looking for other uses of SI.
BasicBlock::iterator BBI = &I, BBFront = I.getParent()->begin();
while (BBI != BBFront) {
--BBI;
// If we found a call to a function, we can't assume it will return, so
// information from below it cannot be propagated above it.
if (isa<CallInst>(BBI) && !isa<IntrinsicInst>(BBI))
break;
// Replace uses of the select or its condition with the known values.
for (Instruction::op_iterator I = BBI->op_begin(), E = BBI->op_end();
I != E; ++I) {
if (*I == SI) {
*I = SI->getOperand(NonNullOperand);
Worklist.Add(BBI);
} else if (*I == SelectCond) {
*I = NonNullOperand == 1 ? ConstantInt::getTrue(BBI->getContext()) :
ConstantInt::getFalse(BBI->getContext());
Worklist.Add(BBI);
}
}
// If we past the instruction, quit looking for it.
if (&*BBI == SI)
SI = 0;
if (&*BBI == SelectCond)
SelectCond = 0;
// If we ran out of things to eliminate, break out of the loop.
if (SelectCond == 0 && SI == 0)
break;
}
return true;
}
示例4: getNullValue
/// GetShiftedValue - When CanEvaluateShifted returned true for an expression,
/// this value inserts the new computation that produces the shifted value.
static Value *GetShiftedValue(Value *V, unsigned NumBits, bool isLeftShift,
InstCombiner &IC) {
// We can always evaluate constants shifted.
if (Constant *C = dyn_cast<Constant>(V)) {
if (isLeftShift)
V = IC.Builder->CreateShl(C, NumBits);
else
V = IC.Builder->CreateLShr(C, NumBits);
// If we got a constantexpr back, try to simplify it with TD info.
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
V = ConstantFoldConstantExpression(CE, IC.getDataLayout(),
IC.getTargetLibraryInfo());
return V;
}
Instruction *I = cast<Instruction>(V);
IC.Worklist.Add(I);
switch (I->getOpcode()) {
default: llvm_unreachable("Inconsistency with CanEvaluateShifted");
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
// Bitwise operators can all arbitrarily be arbitrarily evaluated shifted.
I->setOperand(0, GetShiftedValue(I->getOperand(0), NumBits,isLeftShift,IC));
I->setOperand(1, GetShiftedValue(I->getOperand(1), NumBits,isLeftShift,IC));
return I;
case Instruction::Shl: {
BinaryOperator *BO = cast<BinaryOperator>(I);
unsigned TypeWidth = BO->getType()->getScalarSizeInBits();
// We only accept shifts-by-a-constant in CanEvaluateShifted.
ConstantInt *CI = cast<ConstantInt>(BO->getOperand(1));
// We can always fold shl(c1)+shl(c2) -> shl(c1+c2).
if (isLeftShift) {
// If this is oversized composite shift, then unsigned shifts get 0.
unsigned NewShAmt = NumBits+CI->getZExtValue();
if (NewShAmt >= TypeWidth)
return Constant::getNullValue(I->getType());
BO->setOperand(1, ConstantInt::get(BO->getType(), NewShAmt));
BO->setHasNoUnsignedWrap(false);
BO->setHasNoSignedWrap(false);
return I;
}
// We turn shl(c)+lshr(c) -> and(c2) if the input doesn't already have
// zeros.
if (CI->getValue() == NumBits) {
APInt Mask(APInt::getLowBitsSet(TypeWidth, TypeWidth - NumBits));
V = IC.Builder->CreateAnd(BO->getOperand(0),
ConstantInt::get(BO->getContext(), Mask));
if (Instruction *VI = dyn_cast<Instruction>(V)) {
VI->moveBefore(BO);
VI->takeName(BO);
}
return V;
}
// We turn shl(c1)+shr(c2) -> shl(c3)+and(c4), but only when we know that
// the and won't be needed.
assert(CI->getZExtValue() > NumBits);
BO->setOperand(1, ConstantInt::get(BO->getType(),
CI->getZExtValue() - NumBits));
BO->setHasNoUnsignedWrap(false);
BO->setHasNoSignedWrap(false);
return BO;
}
case Instruction::LShr: {
BinaryOperator *BO = cast<BinaryOperator>(I);
unsigned TypeWidth = BO->getType()->getScalarSizeInBits();
// We only accept shifts-by-a-constant in CanEvaluateShifted.
ConstantInt *CI = cast<ConstantInt>(BO->getOperand(1));
// We can always fold lshr(c1)+lshr(c2) -> lshr(c1+c2).
if (!isLeftShift) {
// If this is oversized composite shift, then unsigned shifts get 0.
unsigned NewShAmt = NumBits+CI->getZExtValue();
if (NewShAmt >= TypeWidth)
return Constant::getNullValue(BO->getType());
BO->setOperand(1, ConstantInt::get(BO->getType(), NewShAmt));
BO->setIsExact(false);
return I;
}
// We turn lshr(c)+shl(c) -> and(c2) if the input doesn't already have
// zeros.
if (CI->getValue() == NumBits) {
APInt Mask(APInt::getHighBitsSet(TypeWidth, TypeWidth - NumBits));
V = IC.Builder->CreateAnd(I->getOperand(0),
ConstantInt::get(BO->getContext(), Mask));
if (Instruction *VI = dyn_cast<Instruction>(V)) {
VI->moveBefore(I);
VI->takeName(I);
}
//.........这里部分代码省略.........
示例5: op
/*
BalanceTree(root I)
worklist: set
leaves: vector
mark I visited
Push(worklist, Ra. Rb)
// find all the leaves of the tree rooted at I
while worklist not empty
// look backwards following def-use from use
T = ’R1 <- op1, Ra1, Rb1’ = Def(Pop(worklist))
if T is a root
// balance computes weight in this case
if T not visited
BalanceTree(T)
SortedInsert(leaves, T, Weight(T))
else if op(T) == op(I)
// add uses to worklist
Push(worklist, Ra1, Rb1)
*/
BinaryOperator* balanceTree(BinaryOperator* root, std::map<Instruction*,bool>& visitMap, std::vector<BinaryOperator*>& roots)
{
assert(root);
if(visitMap[root])
return NULL;
std::list<Value*> worklist;
std::set<std::pair<int,Value*>,weight_less_than> leaves;
visitMap[root] = true;
worklist.push_back( root->getOperand(0) );
worklist.push_back( root->getOperand(1) );
while( !worklist.empty() )
{
Value* v = worklist.front();
worklist.pop_front();
assert(v);
BinaryOperator* T = dynamic_cast<BinaryOperator*>(v);
if( T and std::find(roots.begin(), roots.end(), T) != roots.end() ) // T is a binary operator that exists in the root list
{
if( !visitMap[T] ) //if we havent visited it, replace it with its balanced version
{
T = balanceTree(T, visitMap, roots);
}
if( !T )
{
INTERNAL_ERROR("balanceTree(" << *root << ") failed while attempting to balance leaf node " << *v << "; balance returned NULL!\n");
}
assert( T and "Balancing operation that was a root resulted in NULL being returned from balance function!" );
leaves.insert(std::pair<int,Instruction*>(calculateWeight(T, roots), T));
}
else if( T and !isDifferentOperation(T, root) ) //if T isnt a root, and isnt a different operation than our root, we need to process it
{
worklist.push_back( T->getOperand(0) );
worklist.push_back( T->getOperand(1) );
//remove all of the signed, name, and size call uses
for(Value::use_iterator UI = T->use_begin(); UI != T->use_end();)
{
CallInst* CI = dynamic_cast<CallInst*>(*UI);
if( isROCCCFunctionCall(CI, ROCCCNames::VariableName) or
isROCCCFunctionCall(CI, ROCCCNames::VariableSize) or
isROCCCFunctionCall(CI, ROCCCNames::VariableSigned) )
{
CI->eraseFromParent();
UI = T->use_begin();
}
else
++UI;
}
}
else //T isnt a BinaryOperator, or isn't a root, or is a different operation than our root - just add it as a single leaf
{
leaves.insert(std::pair<int,Value*>(1, v));
}
}
/*
// construct a balanced tree from leaves
while size(leaves) > 1
Ra1 = Dequeue(leaves)
Rb1 = Dequeue(leaves)
T = ’R1 <- op1, Ra1, Rb1’
insert T before I
Weight(R1) = Weight(Ra1) + Weight(Rb1)
SortedInsert(leaves, R1, Weight(R1))
*/
while( leaves.size() > 1 )
{
std::pair<int,Value*> Ra1 = *leaves.begin();
leaves.erase(leaves.begin());
std::pair<int,Value*> Rb1 = *leaves.begin();
leaves.erase(leaves.begin());
int weight = Ra1.first + Rb1.first;
//workaround to create a binary instruction with different operand types; create with undefs, then replace
BinaryOperator* T = BinaryOperator::create(root->getOpcode(), UndefValue::get(root->getType()), UndefValue::get(root->getType()), "tmp", root);
T->setOperand(0, Ra1.second);
T->setOperand(1, Rb1.second);
setSizeInBits(T, getSizeInBits(root));
setValueSigned(T, isValueSigned(root));
leaves.insert(std::pair<int,Value*>(weight, T));
}
BinaryOperator* last_inserted = NULL;
if(leaves.begin() != leaves.end())
last_inserted = dynamic_cast<BinaryOperator*>(leaves.begin()->second);
//.........这里部分代码省略.........