本文整理汇总了C++中Operand::get方法的典型用法代码示例。如果您正苦于以下问题:C++ Operand::get方法的具体用法?C++ Operand::get怎么用?C++ Operand::get使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Operand
的用法示例。
在下文中一共展示了Operand::get方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: RewriteUse
/// This should be called in top-down order of each def that needs its uses
/// rewrited. The order that we visit uses for a given def is irrelevant.
void SILSSAUpdater::RewriteUse(Operand &Op) {
// Replicate function_refs to their uses. SILGen can't build phi nodes for
// them and it would not make much sense anyways.
if (auto *FR = dyn_cast<FunctionRefInst>(Op.get())) {
assert(areIdentical(getAvailVals(AV)) &&
"The function_refs need to have the same value");
SILInstruction *User = Op.getUser();
auto *NewFR = FR->clone(User);
Op.set(SILValue(NewFR, Op.get().getResultNumber()));
return;
} else if (auto *IL = dyn_cast<IntegerLiteralInst>(Op.get()))
if (areIdentical(getAvailVals(AV))) {
// Some llvm intrinsics don't like phi nodes as their constant inputs (e.g
// ctlz).
SILInstruction *User = Op.getUser();
auto *NewIL = IL->clone(User);
Op.set(SILValue(NewIL, Op.get().getResultNumber()));
return;
}
// Again we need to be careful here, because ssa construction (with the
// existing representation) can change the operand from under us.
UseWrapper UW(&Op);
SILInstruction *User = Op.getUser();
SILValue NewVal = GetValueInMiddleOfBlock(User->getParent());
assert(NewVal && "Need a valid value");
((Operand *)UW)->set((SILValue)NewVal);
}
示例2: replaceAllUsesWithUndef
void SILInstruction::replaceAllUsesWithUndef() {
SILModule &Mod = getModule();
while (!use_empty()) {
Operand *Op = *use_begin();
Op->set(SILUndef::get(Op->get()->getType(), Mod));
}
}
示例3: replaceAllUsesWith
void ValueBase::replaceAllUsesWith(ValueBase *RHS) {
assert(this != RHS && "Cannot RAUW a value with itself");
assert(getNumTypes() == RHS->getNumTypes() &&
"An instruction and the value base that it is being replaced by "
"must have the same number of types");
while (!use_empty()) {
Operand *Op = *use_begin();
Op->set(SILValue(RHS, Op->get().getResultNumber()));
}
}
示例4: gatherUsers
bool SILValueOwnershipChecker::gatherUsers(
SmallVectorImpl<BranchPropagatedUser> &lifetimeEndingUsers,
SmallVectorImpl<BranchPropagatedUser> &nonLifetimeEndingUsers,
SmallVectorImpl<BranchPropagatedUser> &implicitRegularUsers) {
// See if Value is guaranteed. If we are guaranteed and not forwarding, then
// we need to look through subobject uses for more uses. Otherwise, if we are
// forwarding, we do not create any lifetime ending users/non lifetime ending
// users since we verify against our base.
auto ownershipKind = value.getOwnershipKind();
bool isGuaranteed = ownershipKind == ValueOwnershipKind::Guaranteed;
bool isOwned = ownershipKind == ValueOwnershipKind::Owned;
if (isGuaranteed && isGuaranteedForwardingValue(value))
return true;
// Then gather up our initial list of users.
SmallVector<Operand *, 8> users;
std::copy(value->use_begin(), value->use_end(), std::back_inserter(users));
auto addCondBranchToList = [](SmallVectorImpl<BranchPropagatedUser> &list,
CondBranchInst *cbi, unsigned operandIndex) {
if (cbi->isConditionOperandIndex(operandIndex)) {
list.emplace_back(cbi);
return;
}
bool isTrueOperand = cbi->isTrueOperandIndex(operandIndex);
list.emplace_back(cbi, isTrueOperand ? CondBranchInst::TrueIdx
: CondBranchInst::FalseIdx);
};
bool foundError = false;
while (!users.empty()) {
Operand *op = users.pop_back_val();
SILInstruction *user = op->getUser();
// If this op is a type dependent operand, skip it. It is not interesting
// from an ownership perspective.
if (user->isTypeDependentOperand(*op))
continue;
bool isGuaranteedSubValue = false;
if (isGuaranteed && isGuaranteedForwardingInst(op->getUser())) {
isGuaranteedSubValue = true;
}
auto opOwnershipKindMap = op->getOwnershipKindMap(isGuaranteedSubValue);
// If our ownership kind doesn't match, track that we found an error, emit
// an error message optionally and then continue.
if (!opOwnershipKindMap.canAcceptKind(ownershipKind)) {
foundError = true;
// If we did not support /any/ ownership kind, it means that we found a
// conflicting answer so the kind map that was returned is the empty
// map. Put out a more specific error here.
if (!opOwnershipKindMap.data.any()) {
handleError([&]() {
llvm::errs() << "Function: '" << user->getFunction()->getName()
<< "'\n"
<< "Ill-formed SIL! Unable to compute ownership kind "
"map for user?!\n"
<< "For terminator users, check that successors have "
"compatible ownership kinds.\n"
<< "Value: " << op->get() << "User: " << *user
<< "Operand Number: " << op->getOperandNumber() << '\n'
<< "Conv: " << ownershipKind << "\n\n";
});
continue;
}
handleError([&]() {
llvm::errs() << "Function: '" << user->getFunction()->getName() << "'\n"
<< "Have operand with incompatible ownership?!\n"
<< "Value: " << op->get() << "User: " << *user
<< "Operand Number: " << op->getOperandNumber() << '\n'
<< "Conv: " << ownershipKind << '\n'
<< "OwnershipMap:\n"
<< opOwnershipKindMap << '\n';
});
continue;
}
auto lifetimeConstraint =
opOwnershipKindMap.getLifetimeConstraint(ownershipKind);
if (lifetimeConstraint == UseLifetimeConstraint::MustBeInvalidated) {
LLVM_DEBUG(llvm::dbgs() << " Lifetime Ending User: " << *user);
if (auto *cbi = dyn_cast<CondBranchInst>(user)) {
addCondBranchToList(lifetimeEndingUsers, cbi, op->getOperandNumber());
} else {
lifetimeEndingUsers.emplace_back(user);
}
} else {
LLVM_DEBUG(llvm::dbgs() << " Regular User: " << *user);
if (auto *cbi = dyn_cast<CondBranchInst>(user)) {
addCondBranchToList(nonLifetimeEndingUsers, cbi,
op->getOperandNumber());
} else {
nonLifetimeEndingUsers.emplace_back(user);
}
//.........这里部分代码省略.........
示例5: visitAccessedAddress
void swift::visitAccessedAddress(SILInstruction *I,
llvm::function_ref<void(Operand *)> visitor) {
assert(I->mayReadOrWriteMemory());
// Reference counting instructions do not access user visible memory.
if (isa<RefCountingInst>(I))
return;
if (isa<DeallocationInst>(I))
return;
if (auto apply = FullApplySite::isa(I)) {
visitApplyAccesses(apply, visitor);
return;
}
if (auto builtin = dyn_cast<BuiltinInst>(I)) {
visitBuiltinAddress(builtin, visitor);
return;
}
switch (I->getKind()) {
default:
I->dump();
llvm_unreachable("unexpected memory access.");
case SILInstructionKind::AssignInst:
visitor(&I->getAllOperands()[AssignInst::Dest]);
return;
case SILInstructionKind::CheckedCastAddrBranchInst:
visitor(&I->getAllOperands()[CheckedCastAddrBranchInst::Src]);
visitor(&I->getAllOperands()[CheckedCastAddrBranchInst::Dest]);
return;
case SILInstructionKind::CopyAddrInst:
visitor(&I->getAllOperands()[CopyAddrInst::Src]);
visitor(&I->getAllOperands()[CopyAddrInst::Dest]);
return;
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
case SILInstructionKind::Store##Name##Inst:
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
case SILInstructionKind::Store##Name##Inst:
#include "swift/AST/ReferenceStorage.def"
case SILInstructionKind::StoreInst:
case SILInstructionKind::StoreBorrowInst:
visitor(&I->getAllOperands()[StoreInst::Dest]);
return;
case SILInstructionKind::SelectEnumAddrInst:
visitor(&I->getAllOperands()[0]);
return;
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
case SILInstructionKind::Load##Name##Inst:
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
case SILInstructionKind::Load##Name##Inst:
#include "swift/AST/ReferenceStorage.def"
case SILInstructionKind::InitExistentialAddrInst:
case SILInstructionKind::InjectEnumAddrInst:
case SILInstructionKind::LoadInst:
case SILInstructionKind::LoadBorrowInst:
case SILInstructionKind::OpenExistentialAddrInst:
case SILInstructionKind::SwitchEnumAddrInst:
case SILInstructionKind::UncheckedTakeEnumDataAddrInst:
case SILInstructionKind::UnconditionalCheckedCastInst: {
// Assuming all the above have only a single address operand.
assert(I->getNumOperands() - I->getNumTypeDependentOperands() == 1);
Operand *singleOperand = &I->getAllOperands()[0];
// Check the operand type because UnconditionalCheckedCastInst may operate
// on a non-address.
if (singleOperand->get()->getType().isAddress())
visitor(singleOperand);
return;
}
// Non-access cases: these are marked with memory side effects, but, by
// themselves, do not access formal memory.
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
case SILInstructionKind::Copy##Name##ValueInst:
#include "swift/AST/ReferenceStorage.def"
case SILInstructionKind::AbortApplyInst:
case SILInstructionKind::AllocBoxInst:
case SILInstructionKind::AllocExistentialBoxInst:
case SILInstructionKind::AllocGlobalInst:
case SILInstructionKind::BeginAccessInst:
case SILInstructionKind::BeginApplyInst:
case SILInstructionKind::BeginBorrowInst:
case SILInstructionKind::BeginUnpairedAccessInst:
case SILInstructionKind::BindMemoryInst:
case SILInstructionKind::CheckedCastValueBranchInst:
case SILInstructionKind::CondFailInst:
case SILInstructionKind::CopyBlockInst:
case SILInstructionKind::CopyBlockWithoutEscapingInst:
case SILInstructionKind::CopyValueInst:
case SILInstructionKind::DeinitExistentialAddrInst:
case SILInstructionKind::DeinitExistentialValueInst:
case SILInstructionKind::DestroyAddrInst:
case SILInstructionKind::DestroyValueInst:
case SILInstructionKind::EndAccessInst:
//.........这里部分代码省略.........
示例6: B
/// Simplify the following two frontend patterns:
///
/// %payload_addr = init_enum_data_addr %payload_allocation
/// store %payload to %payload_addr
/// inject_enum_addr %payload_allocation, $EnumType.case
///
/// inject_enum_add %nopayload_allocation, $EnumType.case
///
/// for a concrete enum type $EnumType.case to:
///
/// %1 = enum $EnumType, $EnumType.case, %payload
/// store %1 to %payload_addr
///
/// %1 = enum $EnumType, $EnumType.case
/// store %1 to %nopayload_addr
///
/// We leave the cleaning up to mem2reg.
SILInstruction *
SILCombiner::visitInjectEnumAddrInst(InjectEnumAddrInst *IEAI) {
// Given an inject_enum_addr of a concrete type without payload, promote it to
// a store of an enum. Mem2reg/load forwarding will clean things up for us. We
// can't handle the payload case here due to the flow problems caused by the
// dependency in between the enum and its data.
assert(IEAI->getOperand()->getType().isAddress() && "Must be an address");
Builder.setCurrentDebugScope(IEAI->getDebugScope());
if (IEAI->getOperand()->getType().isAddressOnly(IEAI->getModule())) {
// Check for the following pattern inside the current basic block:
// inject_enum_addr %payload_allocation, $EnumType.case1
// ... no insns storing anything into %payload_allocation
// select_enum_addr %payload_allocation,
// case $EnumType.case1: %Result1,
// case case $EnumType.case2: %bResult2
// ...
//
// Replace the select_enum_addr by %Result1
auto *Term = IEAI->getParent()->getTerminator();
if (isa<CondBranchInst>(Term) || isa<SwitchValueInst>(Term)) {
auto BeforeTerm = std::prev(std::prev(IEAI->getParent()->end()));
auto *SEAI = dyn_cast<SelectEnumAddrInst>(BeforeTerm);
if (!SEAI)
return nullptr;
if (SEAI->getOperand() != IEAI->getOperand())
return nullptr;
SILBasicBlock::iterator II = IEAI->getIterator();
StoreInst *SI = nullptr;
for (;;) {
SILInstruction *CI = &*II;
if (CI == SEAI)
break;
++II;
SI = dyn_cast<StoreInst>(CI);
if (SI) {
if (SI->getDest() == IEAI->getOperand())
return nullptr;
}
// Allow all instructions in between, which don't have any dependency to
// the store.
if (AA->mayWriteToMemory(&*II, IEAI->getOperand()))
return nullptr;
}
auto *InjectedEnumElement = IEAI->getElement();
auto Result = SEAI->getCaseResult(InjectedEnumElement);
// Replace select_enum_addr by the result
replaceInstUsesWith(*SEAI, Result);
return nullptr;
}
// Check for the following pattern inside the current basic block:
// inject_enum_addr %payload_allocation, $EnumType.case1
// ... no insns storing anything into %payload_allocation
// switch_enum_addr %payload_allocation,
// case $EnumType.case1: %bbX,
// case case $EnumType.case2: %bbY
// ...
//
// Replace the switch_enum_addr by select_enum_addr, switch_value.
if (auto *SEI = dyn_cast<SwitchEnumAddrInst>(Term)) {
if (SEI->getOperand() != IEAI->getOperand())
return nullptr;
SILBasicBlock::iterator II = IEAI->getIterator();
StoreInst *SI = nullptr;
for (;;) {
SILInstruction *CI = &*II;
if (CI == SEI)
break;
++II;
SI = dyn_cast<StoreInst>(CI);
if (SI) {
if (SI->getDest() == IEAI->getOperand())
return nullptr;
}
// Allow all instructions in between, which don't have any dependency to
//.........这里部分代码省略.........