本文整理汇总了C++中SmallVectorImpl::clear方法的典型用法代码示例。如果您正苦于以下问题:C++ SmallVectorImpl::clear方法的具体用法?C++ SmallVectorImpl::clear怎么用?C++ SmallVectorImpl::clear使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SmallVectorImpl
的用法示例。
在下文中一共展示了SmallVectorImpl::clear方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: AnalyzeBranch
bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const
{
MachineBasicBlock::iterator I = MBB.end();
MachineBasicBlock::iterator UnCondBrIter = MBB.end();
while (I != MBB.begin()) {
--I;
if (I->isDebugValue())
continue;
//When we see a non-terminator, we are done
if (!isUnpredicatedTerminator(I))
break;
//Terminator is not a branch
if (!I->isBranch())
return true;
//Handle Unconditional branches
if (I->getOpcode() == SP::BA) {
UnCondBrIter = I;
if (!AllowModify) {
TBB = I->getOperand(0).getMBB();
continue;
}
while (llvm::next(I) != MBB.end())
llvm::next(I)->eraseFromParent();
Cond.clear();
FBB = 0;
if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
TBB = 0;
I->eraseFromParent();
I = MBB.end();
UnCondBrIter = MBB.end();
continue;
}
TBB = I->getOperand(0).getMBB();
continue;
}
unsigned Opcode = I->getOpcode();
if (Opcode != SP::BCOND && Opcode != SP::FBCOND)
return true; //Unknown Opcode
SPCC::CondCodes BranchCode = (SPCC::CondCodes)I->getOperand(1).getImm();
if (Cond.empty()) {
MachineBasicBlock *TargetBB = I->getOperand(0).getMBB();
if (AllowModify && UnCondBrIter != MBB.end() &&
MBB.isLayoutSuccessor(TargetBB)) {
//Transform the code
//
// brCC L1
// ba L2
// L1:
// ..
// L2:
//
// into
//
// brnCC L2
// L1:
// ...
// L2:
//
BranchCode = GetOppositeBranchCondition(BranchCode);
MachineBasicBlock::iterator OldInst = I;
BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(Opcode))
.addMBB(UnCondBrIter->getOperand(0).getMBB()).addImm(BranchCode);
BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(SP::BA))
.addMBB(TargetBB);
OldInst->eraseFromParent();
UnCondBrIter->eraseFromParent();
UnCondBrIter = MBB.end();
I = MBB.end();
continue;
}
FBB = TBB;
TBB = I->getOperand(0).getMBB();
Cond.push_back(MachineOperand::CreateImm(BranchCode));
continue;
}
//FIXME: Handle subsequent conditional branches
//For now, we can't handle multiple conditional branches
return true;
}
return false;
//.........这里部分代码省略.........
示例2: while
bool MSP430InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const {
// Start from the bottom of the block and work up, examining the
// terminator instructions.
MachineBasicBlock::iterator I = MBB.end();
while (I != MBB.begin()) {
--I;
if (I->isDebugValue())
continue;
// Working from the bottom, when we see a non-terminator
// instruction, we're done.
if (!isUnpredicatedTerminator(I))
break;
// A terminator that isn't a branch can't easily be handled
// by this analysis.
if (!I->isBranch())
return true;
// Cannot handle indirect branches.
if (I->getOpcode() == MSP430::Br ||
I->getOpcode() == MSP430::Bm)
return true;
// Handle unconditional branches.
if (I->getOpcode() == MSP430::JMP) {
if (!AllowModify) {
TBB = I->getOperand(0).getMBB();
continue;
}
// If the block has any instructions after a JMP, delete them.
while (std::next(I) != MBB.end())
std::next(I)->eraseFromParent();
Cond.clear();
FBB = 0;
// Delete the JMP if it's equivalent to a fall-through.
if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
TBB = 0;
I->eraseFromParent();
I = MBB.end();
continue;
}
// TBB is used to indicate the unconditinal destination.
TBB = I->getOperand(0).getMBB();
continue;
}
// Handle conditional branches.
assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
MSP430CC::CondCodes BranchCode =
static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
if (BranchCode == MSP430CC::COND_INVALID)
return true; // Can't handle weird stuff.
// Working from the bottom, handle the first conditional branch.
if (Cond.empty()) {
FBB = TBB;
TBB = I->getOperand(0).getMBB();
Cond.push_back(MachineOperand::CreateImm(BranchCode));
continue;
}
// Handle subsequent conditional branches. Only handle the case where all
// conditional branches branch to the same destination.
assert(Cond.size() == 1);
assert(TBB);
// Only handle the case where all conditional branches branch to
// the same destination.
if (TBB != I->getOperand(0).getMBB())
return true;
MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();
// If the conditions are the same, we can leave them alone.
if (OldBranchCode == BranchCode)
continue;
return true;
}
return false;
}
示例3: ParseOpenMPSimpleVarList
/// \brief Parses list of simple variables for '#pragma omp threadprivate'
/// directive.
///
/// simple-variable-list:
/// '(' id-expression {, id-expression} ')'
///
bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
SmallVectorImpl<Expr *> &VarList,
bool AllowScopeSpecifier) {
VarList.clear();
// Parse '('.
BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
if (T.expectAndConsume(diag::err_expected_lparen_after,
getOpenMPDirectiveName(Kind)))
return true;
bool IsCorrect = true;
bool NoIdentIsFound = true;
// Read tokens while ')' or annot_pragma_openmp_end is not found.
while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
CXXScopeSpec SS;
SourceLocation TemplateKWLoc;
UnqualifiedId Name;
// Read var name.
Token PrevTok = Tok;
NoIdentIsFound = false;
if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false)) {
IsCorrect = false;
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
} else if (ParseUnqualifiedId(SS, false, false, false, ParsedType(),
TemplateKWLoc, Name)) {
IsCorrect = false;
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
} else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::annot_pragma_openmp_end)) {
IsCorrect = false;
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
Diag(PrevTok.getLocation(), diag::err_expected)
<< tok::identifier
<< SourceRange(PrevTok.getLocation(), PrevTokLocation);
} else {
DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name);
ExprResult Res =
Actions.ActOnOpenMPIdExpression(getCurScope(), SS, NameInfo);
if (Res.isUsable())
VarList.push_back(Res.get());
}
// Consume ','.
if (Tok.is(tok::comma)) {
ConsumeToken();
}
}
if (NoIdentIsFound) {
Diag(Tok, diag::err_expected) << tok::identifier;
IsCorrect = false;
}
// Parse ')'.
IsCorrect = !T.consumeClose() && IsCorrect;
return !IsCorrect && VarList.empty();
}
示例4: Res
static void
updateSSAForUseOfInst(SILSSAUpdater &Updater,
SmallVectorImpl<SILArgument*> &InsertedPHIs,
const llvm::DenseMap<ValueBase *, SILValue> &ValueMap,
SILBasicBlock *Header, SILBasicBlock *EntryCheckBlock,
ValueBase *Inst) {
if (Inst->use_empty())
return;
// Find the mapped instruction.
assert(ValueMap.count(Inst) && "Expected to find value in map!");
SILValue MappedValue = ValueMap.find(Inst)->second;
auto *MappedInst = MappedValue.getDef();
assert(MappedValue);
assert(MappedInst);
// For each use of a specific result value of the instruction.
for (unsigned i = 0, e = Inst->getNumTypes(); i != e; ++i) {
SILValue Res(Inst, i);
// For block arguments, MappedValue is already indexed to indicate the
// single result value that feeds the argument. In this case, i==0 because
// SILArgument only produces one value.
SILValue MappedRes =
isa<SILArgument>(Inst) ? MappedValue : SILValue(MappedInst, i);
assert(Res.getType() == MappedRes.getType() && "The types must match");
InsertedPHIs.clear();
Updater.Initialize(Res.getType());
Updater.AddAvailableValue(Header, Res);
Updater.AddAvailableValue(EntryCheckBlock, MappedRes);
// Because of the way that phi nodes are represented we have to collect all
// uses before we update SSA. Modifying one phi node can invalidate another
// unrelated phi nodes operands through the common branch instruction (that
// has to be modified). This would invalidate a plain ValueUseIterator.
// Instead we collect uses wrapping uses in branches specially so that we
// can reconstruct the use even after the branch has been modified.
SmallVector<UseWrapper, 8> StoredUses;
for (auto *U : Res.getUses())
StoredUses.push_back(UseWrapper(U));
for (auto U : StoredUses) {
Operand *Use = U;
SILInstruction *User = Use->getUser();
assert(User && "Missing user");
// Ignore uses in the same basic block.
if (User->getParent() == Header)
continue;
assert(User->getParent() != EntryCheckBlock &&
"The entry check block should dominate the header");
Updater.RewriteUse(*Use);
}
// Canonicalize inserted phis to avoid extra BB Args.
for (SILArgument *Arg : InsertedPHIs) {
if (SILInstruction *Inst = replaceBBArgWithCast(Arg)) {
Arg->replaceAllUsesWith(Inst);
// DCE+SimplifyCFG runs as a post-pass cleanup.
// DCE replaces dead arg values with undef.
// SimplifyCFG deletes the dead BB arg.
}
}
}
}
示例5: analyzeBranch
bool ARCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const {
TBB = FBB = nullptr;
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin())
return false;
--I;
while (isPredicated(*I) || I->isTerminator() || I->isDebugValue()) {
// Flag to be raised on unanalyzeable instructions. This is useful in cases
// where we want to clean up on the end of the basic block before we bail
// out.
bool CantAnalyze = false;
// Skip over DEBUG values and predicated nonterminators.
while (I->isDebugValue() || !I->isTerminator()) {
if (I == MBB.begin())
return false;
--I;
}
if (isJumpOpcode(I->getOpcode())) {
// Indirect branches and jump tables can't be analyzed, but we still want
// to clean up any instructions at the tail of the basic block.
CantAnalyze = true;
} else if (isUncondBranchOpcode(I->getOpcode())) {
TBB = I->getOperand(0).getMBB();
} else if (isCondBranchOpcode(I->getOpcode())) {
// Bail out if we encounter multiple conditional branches.
if (!Cond.empty())
return true;
assert(!FBB && "FBB should have been null.");
FBB = TBB;
TBB = I->getOperand(0).getMBB();
Cond.push_back(I->getOperand(1));
Cond.push_back(I->getOperand(2));
Cond.push_back(I->getOperand(3));
} else if (I->isReturn()) {
// Returns can't be analyzed, but we should run cleanup.
CantAnalyze = !isPredicated(*I);
} else {
// We encountered other unrecognized terminator. Bail out immediately.
return true;
}
// Cleanup code - to be run for unpredicated unconditional branches and
// returns.
if (!isPredicated(*I) && (isUncondBranchOpcode(I->getOpcode()) ||
isJumpOpcode(I->getOpcode()) || I->isReturn())) {
// Forget any previous condition branch information - it no longer
// applies.
Cond.clear();
FBB = nullptr;
// If we can modify the function, delete everything below this
// unconditional branch.
if (AllowModify) {
MachineBasicBlock::iterator DI = std::next(I);
while (DI != MBB.end()) {
MachineInstr &InstToDelete = *DI;
++DI;
InstToDelete.eraseFromParent();
}
}
}
if (CantAnalyze)
return true;
if (I == MBB.begin())
return false;
--I;
}
// We made it past the terminators without bailing out - we must have
// analyzed this branch successfully.
return false;
}
示例6: analyzeBranch
// The AnalyzeBranch function is used to examine conditional instructions and
// remove unnecessary instructions. This method is used by BranchFolder and
// IfConverter machine function passes to improve the CFG.
// - TrueBlock is set to the destination if condition evaluates true (it is the
// nullptr if the destination is the fall-through branch);
// - FalseBlock is set to the destination if condition evaluates to false (it
// is the nullptr if the branch is unconditional);
// - condition is populated with machine operands needed to generate the branch
// to insert in InsertBranch;
// Returns: false if branch could successfully be analyzed.
bool LanaiInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TrueBlock,
MachineBasicBlock *&FalseBlock,
SmallVectorImpl<MachineOperand> &Condition,
bool AllowModify) const {
// Iterator to current instruction being considered.
MachineBasicBlock::iterator Instruction = MBB.end();
// Start from the bottom of the block and work up, examining the
// terminator instructions.
while (Instruction != MBB.begin()) {
--Instruction;
// Skip over debug values.
if (Instruction->isDebugValue())
continue;
// Working from the bottom, when we see a non-terminator
// instruction, we're done.
if (!isUnpredicatedTerminator(*Instruction))
break;
// A terminator that isn't a branch can't easily be handled
// by this analysis.
if (!Instruction->isBranch())
return true;
// Handle unconditional branches.
if (Instruction->getOpcode() == Lanai::BT) {
if (!AllowModify) {
TrueBlock = Instruction->getOperand(0).getMBB();
continue;
}
// If the block has any instructions after a branch, delete them.
while (std::next(Instruction) != MBB.end()) {
std::next(Instruction)->eraseFromParent();
}
Condition.clear();
FalseBlock = nullptr;
// Delete the jump if it's equivalent to a fall-through.
if (MBB.isLayoutSuccessor(Instruction->getOperand(0).getMBB())) {
TrueBlock = nullptr;
Instruction->eraseFromParent();
Instruction = MBB.end();
continue;
}
// TrueBlock is used to indicate the unconditional destination.
TrueBlock = Instruction->getOperand(0).getMBB();
continue;
}
// Handle conditional branches
unsigned Opcode = Instruction->getOpcode();
if (Opcode != Lanai::BRCC)
return true; // Unknown opcode.
// Multiple conditional branches are not handled here so only proceed if
// there are no conditions enqueued.
if (Condition.empty()) {
LPCC::CondCode BranchCond =
static_cast<LPCC::CondCode>(Instruction->getOperand(1).getImm());
// TrueBlock is the target of the previously seen unconditional branch.
FalseBlock = TrueBlock;
TrueBlock = Instruction->getOperand(0).getMBB();
Condition.push_back(MachineOperand::CreateImm(BranchCond));
continue;
}
// Multiple conditional branches are not handled.
return true;
}
// Return false indicating branch successfully analyzed.
return false;
}
示例7: WriteGlobalInit
/// \brief Function to convert constant initializers for global
/// variables into corresponding bitcode. Takes advantage that these
/// global variable initializations are normalized (see
/// lib/Transforms/NaCl/FlattenGlobals.cpp).
void WriteGlobalInit(const Constant *C, unsigned GlobalVarID,
SmallVectorImpl<uint32_t> &Vals,
const NaClValueEnumerator &VE,
NaClBitstreamWriter &Stream) {
if (ArrayType *Ty = dyn_cast<ArrayType>(C->getType())) {
if (!Ty->getElementType()->isIntegerTy(8))
report_fatal_error("Global array initializer not i8");
uint32_t Size = Ty->getNumElements();
if (isa<ConstantAggregateZero>(C)) {
Vals.push_back(Size);
Stream.EmitRecord(naclbitc::GLOBALVAR_ZEROFILL, Vals,
GLOBALVAR_ZEROFILL_ABBREV);
Vals.clear();
} else {
const ConstantDataSequential *CD = cast<ConstantDataSequential>(C);
StringRef Data = CD->getRawDataValues();
for (size_t i = 0; i < Size; ++i) {
Vals.push_back(Data[i] & 0xFF);
}
Stream.EmitRecord(naclbitc::GLOBALVAR_DATA, Vals,
GLOBALVAR_DATA_ABBREV);
Vals.clear();
}
return;
}
if (VE.IsIntPtrType(C->getType())) {
// This constant defines a relocation. Start by verifying the
// relocation is of the right form.
const ConstantExpr *CE = dyn_cast<ConstantExpr>(C);
if (CE == 0)
report_fatal_error("Global i32 initializer not constant");
assert(CE);
int32_t Addend = 0;
if (CE->getOpcode() == Instruction::Add) {
const ConstantInt *AddendConst = dyn_cast<ConstantInt>(CE->getOperand(1));
if (AddendConst == 0)
report_fatal_error("Malformed addend in global relocation initializer");
Addend = AddendConst->getSExtValue();
CE = dyn_cast<ConstantExpr>(CE->getOperand(0));
if (CE == 0)
report_fatal_error(
"Base of global relocation initializer not constant");
}
if (CE->getOpcode() != Instruction::PtrToInt)
report_fatal_error("Global relocation base doesn't contain ptrtoint");
GlobalValue *GV = dyn_cast<GlobalValue>(CE->getOperand(0));
if (GV == 0)
report_fatal_error(
"Argument of ptrtoint in global relocation no global value");
// Now generate the corresponding relocation record.
unsigned RelocID = VE.getValueID(GV);
// This is a value index.
unsigned AbbrevToUse = GLOBALVAR_RELOC_ABBREV;
Vals.push_back(RelocID);
if (Addend) {
Vals.push_back(Addend);
AbbrevToUse = GLOBALVAR_RELOC_WITH_ADDEND_ABBREV;
}
Stream.EmitRecord(naclbitc::GLOBALVAR_RELOC, Vals, AbbrevToUse);
Vals.clear();
return;
}
report_fatal_error("Global initializer is not a SimpleElement");
}
示例8: AnalyzeBranch
bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const {
// Most of the code and comments here are boilerplate.
// Start from the bottom of the block and work up, examining the
// terminator instructions.
MachineBasicBlock::iterator I = MBB.end();
while (I != MBB.begin()) {
--I;
if (I->isDebugValue())
continue;
// Working from the bottom, when we see a non-terminator instruction, we're
// done.
if (!isUnpredicatedTerminator(I))
break;
// A terminator that isn't a branch can't easily be handled by this
// analysis.
unsigned ThisCond;
const MachineOperand *ThisTarget;
if (!isBranch(I, ThisCond, ThisTarget))
return true;
// Can't handle indirect branches.
if (!ThisTarget->isMBB())
return true;
if (ThisCond == SystemZ::CCMASK_ANY) {
// Handle unconditional branches.
if (!AllowModify) {
TBB = ThisTarget->getMBB();
continue;
}
// If the block has any instructions after a JMP, delete them.
while (llvm::next(I) != MBB.end())
llvm::next(I)->eraseFromParent();
Cond.clear();
FBB = 0;
// Delete the JMP if it's equivalent to a fall-through.
if (MBB.isLayoutSuccessor(ThisTarget->getMBB())) {
TBB = 0;
I->eraseFromParent();
I = MBB.end();
continue;
}
// TBB is used to indicate the unconditinal destination.
TBB = ThisTarget->getMBB();
continue;
}
// Working from the bottom, handle the first conditional branch.
if (Cond.empty()) {
// FIXME: add X86-style branch swap
FBB = TBB;
TBB = ThisTarget->getMBB();
Cond.push_back(MachineOperand::CreateImm(ThisCond));
continue;
}
// Handle subsequent conditional branches.
assert(Cond.size() == 1);
assert(TBB);
// Only handle the case where all conditional branches branch to the same
// destination.
if (TBB != ThisTarget->getMBB())
return true;
// If the conditions are the same, we can leave them alone.
unsigned OldCond = Cond[0].getImm();
if (OldCond == ThisCond)
continue;
// FIXME: Try combining conditions like X86 does. Should be easy on Z!
}
return false;
}
示例9: AnalyzeBranch
bool AVRInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const {
// Start from the bottom of the block and work up, examining the
// terminator instructions.
MachineBasicBlock::iterator I = MBB.end();
MachineBasicBlock::iterator UnCondBrIter = MBB.end();
while (I != MBB.begin()) {
--I;
if (I->isDebugValue()) {
continue;
}
// Working from the bottom, when we see a non-terminator
// instruction, we're done.
if (!isUnpredicatedTerminator(*I)) {
break;
}
// A terminator that isn't a branch can't easily be handled
// by this analysis.
if (!I->getDesc().isBranch()) {
return true;
}
// Handle unconditional branches.
//:TODO: add here jmp
if (I->getOpcode() == AVR::RJMPk) {
UnCondBrIter = I;
if (!AllowModify) {
TBB = I->getOperand(0).getMBB();
continue;
}
// If the block has any instructions after a JMP, delete them.
while (std::next(I) != MBB.end()) {
std::next(I)->eraseFromParent();
}
Cond.clear();
FBB = 0;
// Delete the JMP if it's equivalent to a fall-through.
if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
TBB = 0;
I->eraseFromParent();
I = MBB.end();
UnCondBrIter = MBB.end();
continue;
}
// TBB is used to indicate the unconditinal destination.
TBB = I->getOperand(0).getMBB();
continue;
}
// Handle conditional branches.
AVRCC::CondCodes BranchCode = getCondFromBranchOpc(I->getOpcode());
if (BranchCode == AVRCC::COND_INVALID) {
return true; // Can't handle indirect branch.
}
// Working from the bottom, handle the first conditional branch.
if (Cond.empty()) {
MachineBasicBlock *TargetBB = I->getOperand(0).getMBB();
if (AllowModify && UnCondBrIter != MBB.end() &&
MBB.isLayoutSuccessor(TargetBB)) {
// If we can modify the code and it ends in something like:
//
// jCC L1
// jmp L2
// L1:
// ...
// L2:
//
// Then we can change this to:
//
// jnCC L2
// L1:
// ...
// L2:
//
// Which is a bit more efficient.
// We conditionally jump to the fall-through block.
BranchCode = getOppositeCondition(BranchCode);
unsigned JNCC = getBrCond(BranchCode).getOpcode();
MachineBasicBlock::iterator OldInst = I;
BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(JNCC))
.addMBB(UnCondBrIter->getOperand(0).getMBB());
BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(AVR::RJMPk))
.addMBB(TargetBB);
OldInst->eraseFromParent();
UnCondBrIter->eraseFromParent();
//.........这里部分代码省略.........
示例10: computeConnectedComponents
unsigned ConstraintGraph::computeConnectedComponents(
SmallVectorImpl<TypeVariableType *> &typeVars,
SmallVectorImpl<unsigned> &components) {
// Track those type variables that the caller cares about.
llvm::SmallPtrSet<TypeVariableType *, 4> typeVarSubset(typeVars.begin(),
typeVars.end());
typeVars.clear();
// Initialize the components with component == # of type variables,
// a sentinel value indicating
unsigned numTypeVariables = TypeVariables.size();
components.assign(numTypeVariables, numTypeVariables);
// Perform a depth-first search from each type variable to identify
// what component it is in.
unsigned numComponents = 0;
for (unsigned i = 0; i != numTypeVariables; ++i) {
auto typeVar = TypeVariables[i];
// Look up the node for this type variable.
auto nodeAndIndex = lookupNode(typeVar);
// If we're already assigned a component for this node, skip it.
unsigned &curComponent = components[nodeAndIndex.second];
if (curComponent != numTypeVariables)
continue;
// Record this component.
unsigned component = numComponents++;
// Note that this node is part of this component, then visit it.
curComponent = component;
connectedComponentsDFS(*this, nodeAndIndex.first, component, components);
}
// Figure out which components have unbound type variables; these
// are the only components and type variables we want to report.
SmallVector<bool, 4> componentHasUnboundTypeVar(numComponents, false);
for (unsigned i = 0; i != numTypeVariables; ++i) {
// If this type variable has a fixed type, skip it.
if (CS.getFixedType(TypeVariables[i]))
continue;
// If we only care about a subset, and this type variable isn't in that
// subset, skip it.
if (!typeVarSubset.empty() && typeVarSubset.count(TypeVariables[i]) == 0)
continue;
componentHasUnboundTypeVar[components[i]] = true;
}
// Renumber the old components to the new components.
SmallVector<unsigned, 4> componentRenumbering(numComponents, 0);
numComponents = 0;
for (unsigned i = 0, n = componentHasUnboundTypeVar.size(); i != n; ++i) {
// Skip components that have no unbound type variables.
if (!componentHasUnboundTypeVar[i])
continue;
componentRenumbering[i] = numComponents++;
}
// Copy over the type variables in the live components and remap
// component numbers.
unsigned outIndex = 0;
for (unsigned i = 0, n = TypeVariables.size(); i != n; ++i) {
// Skip type variables in dead components.
if (!componentHasUnboundTypeVar[components[i]])
continue;
typeVars.push_back(TypeVariables[i]);
components[outIndex] = componentRenumbering[components[i]];
++outIndex;
}
components.erase(components.begin() + outIndex, components.end());
return numComponents;
}
示例11: while
bool DCPU16InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const {
// Start from the bottom of the block and work up, examining the
// terminator instructions.
MachineBasicBlock::iterator I = MBB.end();
while (I != MBB.begin()) {
--I;
if (I->isDebugValue())
continue;
// Working from the bottom, when we see a non-terminator
// instruction, we're done.
if (!isUnpredicatedTerminator(I))
break;
// A terminator that isn't a branch can't easily be handled
// by this analysis.
if (!I->isBranch())
return true;
// Cannot handle indirect branches.
if (I->getOpcode() == DCPU16::Br ||
I->getOpcode() == DCPU16::Bm)
return true;
// Handle unconditional branches.
if (I->getOpcode() == DCPU16::JMP) {
if (!AllowModify) {
TBB = I->getOperand(0).getMBB();
continue;
}
// If the block has any instructions after a JMP, delete them.
while (llvm::next(I) != MBB.end())
llvm::next(I)->eraseFromParent();
Cond.clear();
FBB = 0;
// Delete the JMP if it's equivalent to a fall-through.
if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
TBB = 0;
I->eraseFromParent();
I = MBB.end();
continue;
}
// TBB is used to indicate the unconditinal destination.
TBB = I->getOperand(0).getMBB();
continue;
}
// Handle conditional branches.
assert(isBR_CC(I->getOpcode()) && "Invalid conditional branch");
DCPU16CC::CondCodes BranchCode =
static_cast<DCPU16CC::CondCodes>(I->getOperand(0).getImm());
if (BranchCode == DCPU16CC::COND_INVALID)
return true; // Can't handle weird stuff.
MachineOperand LHS = I->getOperand(1);
MachineOperand RHS = I->getOperand(2);
// Working from the bottom, handle the first conditional branch.
if (Cond.empty()) {
FBB = TBB;
TBB = I->getOperand(3).getMBB();
Cond.push_back(MachineOperand::CreateImm(I->getOpcode()));
Cond.push_back(MachineOperand::CreateImm(BranchCode));
Cond.push_back(LHS);
Cond.push_back(RHS);
continue;
}
assert(Cond.size() == 4);
assert(TBB);
// Is it a complex CC?
DCPU16CC::CondCodes complexCC;
if ((BranchCode == DCPU16CC::COND_E)
&& AcceptsAdditionalEqualityCheck((DCPU16CC::CondCodes) Cond[1].getImm(), &complexCC)
&& (TBB == I->getOperand(3).getMBB())
// This should actually check for equality but that's just too much code...
&& (((Cond[2].getType() == LHS.getType()) && (Cond[3].getType() == RHS.getType()))
|| ((Cond[2].getType() == RHS.getType()) && (Cond[3].getType() == LHS.getType())))) {
Cond[1] = MachineOperand::CreateImm(complexCC);
}
break;
}
return false;
}