Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
Show First 20 Lines • Show All 1,370 Lines • ▼ Show 20 Lines | HoistTerminator: | ||||
// Update any PHI nodes in our new successors. | // Update any PHI nodes in our new successors. | ||||
for (BasicBlock *Succ : successors(BB1)) | for (BasicBlock *Succ : successors(BB1)) | ||||
AddPredecessorToBlock(Succ, BIParent, BB1); | AddPredecessorToBlock(Succ, BIParent, BB1); | ||||
EraseTerminatorInstAndDCECond(BI); | EraseTerminatorInstAndDCECond(BI); | ||||
return true; | return true; | ||||
} | } | ||||
// Is it legal to place a variable in operand \c OpIdx of \c I? | |||||
// FIXME: This should be promoted to Instruction. | |||||
static bool canReplaceOperandWithVariable(const Instruction *I, | |||||
unsigned OpIdx) { | |||||
// We can't have a PHI with a metadata type. | |||||
if (I->getOperand(OpIdx)->getType()->isMetadataTy()) | |||||
return false; | |||||
// Early exit. | |||||
if (!isa<Constant>(I->getOperand(OpIdx))) | |||||
return true; | |||||
switch (I->getOpcode()) { | |||||
default: | |||||
return true; | |||||
case Instruction::Call: | |||||
case Instruction::Invoke: | |||||
// FIXME: many arithmetic intrinsics have no issue taking a | |||||
// variable, however it's hard to distingish these from | |||||
// specials such as @llvm.frameaddress that require a constant. | |||||
if (isa<IntrinsicInst>(I)) | |||||
return false; | |||||
// Constant bundle operands may need to retain their constant-ness for | |||||
// correctness. | |||||
if (ImmutableCallSite(I).isBundleOperand(OpIdx)) | |||||
return false; | |||||
return true; | |||||
case Instruction::ShuffleVector: | |||||
// Shufflevector masks are constant. | |||||
return OpIdx != 2; | |||||
case Instruction::ExtractValue: | |||||
case Instruction::InsertValue: | |||||
// All operands apart from the first are constant. | |||||
return OpIdx == 0; | |||||
case Instruction::Alloca: | |||||
return false; | |||||
case Instruction::GetElementPtr: | |||||
if (OpIdx == 0) | |||||
return true; | |||||
gep_type_iterator It = std::next(gep_type_begin(I), OpIdx - 1); | |||||
return It.isSequential(); | |||||
} | |||||
} | |||||
// All instructions in Insts belong to different blocks that all unconditionally | // All instructions in Insts belong to different blocks that all unconditionally | ||||
// branch to a common successor. Analyze each instruction and return true if it | // branch to a common successor. Analyze each instruction and return true if it | ||||
// would be possible to sink them into their successor, creating one common | // would be possible to sink them into their successor, creating one common | ||||
// instruction instead. For every value that would be required to be provided by | // instruction instead. For every value that would be required to be provided by | ||||
// PHI node (because an operand varies in each input block), add to PHIOperands. | // PHI node (because an operand varies in each input block), add to PHIOperands. | ||||
static bool canSinkInstructions( | static bool canSinkInstructions( | ||||
ArrayRef<Instruction *> Insts, | ArrayRef<Instruction *> Insts, | ||||
DenseMap<Instruction *, SmallVector<Value *, 4>> &PHIOperands) { | DenseMap<Instruction *, SmallVector<Value *, 4>> &PHIOperands) { | ||||
▲ Show 20 Lines • Show All 4,609 Lines • Show Last 20 Lines |