mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
[InstSimplify] Teach InstSimplify how to simplify extractvalue
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242007 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6c57f2fe84
commit
5501985a58
@ -72,6 +72,12 @@ namespace llvm {
|
|||||||
Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
|
Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
|
||||||
ArrayRef<unsigned> Idxs);
|
ArrayRef<unsigned> Idxs);
|
||||||
|
|
||||||
|
/// \brief Attempt to constant fold an extractvalue instruction with the
|
||||||
|
/// specified operands and indices. The constant result is returned if
|
||||||
|
/// successful; if not, null is returned.
|
||||||
|
Constant *ConstantFoldExtractValueInstruction(Constant *Agg,
|
||||||
|
ArrayRef<unsigned> Idxs);
|
||||||
|
|
||||||
/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
|
/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
|
||||||
/// produce if it is constant and determinable. If this is not determinable,
|
/// produce if it is constant and determinable. If this is not determinable,
|
||||||
/// return null.
|
/// return null.
|
||||||
|
@ -244,6 +244,15 @@ namespace llvm {
|
|||||||
AssumptionCache *AC = nullptr,
|
AssumptionCache *AC = nullptr,
|
||||||
const Instruction *CxtI = nullptr);
|
const Instruction *CxtI = nullptr);
|
||||||
|
|
||||||
|
/// \brief Given operands for an ExtractValueInst, see if we can fold the
|
||||||
|
/// result. If not, this returns null.
|
||||||
|
Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
|
||||||
|
const DataLayout &DL,
|
||||||
|
const TargetLibraryInfo *TLI = nullptr,
|
||||||
|
const DominatorTree *DT = nullptr,
|
||||||
|
AssumptionCache *AC = nullptr,
|
||||||
|
const Instruction *CxtI = nullptr);
|
||||||
|
|
||||||
/// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
|
/// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
|
||||||
/// the result. If not, this returns null.
|
/// the result. If not, this returns null.
|
||||||
Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout &DL,
|
Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout &DL,
|
||||||
|
@ -3520,6 +3520,41 @@ Value *llvm::SimplifyInsertValueInst(
|
|||||||
RecursionLimit);
|
RecursionLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// SimplifyExtractValueInst - Given operands for an ExtractValueInst, see if we
|
||||||
|
/// can fold the result. If not, this returns null.
|
||||||
|
static Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
|
||||||
|
const Query &, unsigned) {
|
||||||
|
if (auto *CAgg = dyn_cast<Constant>(Agg))
|
||||||
|
return ConstantFoldExtractValueInstruction(CAgg, Idxs);
|
||||||
|
|
||||||
|
// extractvalue x, (insertvalue y, elt, n), n -> elt
|
||||||
|
unsigned NumIdxs = Idxs.size();
|
||||||
|
for (auto *IVI = dyn_cast<InsertValueInst>(Agg); IVI != nullptr;
|
||||||
|
IVI = dyn_cast<InsertValueInst>(IVI->getAggregateOperand())) {
|
||||||
|
ArrayRef<unsigned> InsertValueIdxs = IVI->getIndices();
|
||||||
|
unsigned NumInsertValueIdxs = InsertValueIdxs.size();
|
||||||
|
unsigned NumCommonIdxs = std::min(NumInsertValueIdxs, NumIdxs);
|
||||||
|
if (InsertValueIdxs.slice(0, NumCommonIdxs) ==
|
||||||
|
Idxs.slice(0, NumCommonIdxs)) {
|
||||||
|
if (NumIdxs == NumInsertValueIdxs)
|
||||||
|
return IVI->getInsertedValueOperand();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value *llvm::SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
|
||||||
|
const DataLayout &DL,
|
||||||
|
const TargetLibraryInfo *TLI,
|
||||||
|
const DominatorTree *DT,
|
||||||
|
AssumptionCache *AC,
|
||||||
|
const Instruction *CxtI) {
|
||||||
|
return ::SimplifyExtractValueInst(Agg, Idxs, Query(DL, TLI, DT, AC, CxtI),
|
||||||
|
RecursionLimit);
|
||||||
|
}
|
||||||
|
|
||||||
/// SimplifyPHINode - See if we can fold the given phi. If not, returns null.
|
/// SimplifyPHINode - See if we can fold the given phi. If not, returns null.
|
||||||
static Value *SimplifyPHINode(PHINode *PN, const Query &Q) {
|
static Value *SimplifyPHINode(PHINode *PN, const Query &Q) {
|
||||||
// If all of the PHI's incoming values are the same then replace the PHI node
|
// If all of the PHI's incoming values are the same then replace the PHI node
|
||||||
@ -3929,6 +3964,12 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
|
|||||||
IV->getIndices(), DL, TLI, DT, AC, I);
|
IV->getIndices(), DL, TLI, DT, AC, I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Instruction::ExtractValue: {
|
||||||
|
auto *EVI = cast<ExtractValueInst>(I);
|
||||||
|
Result = SimplifyExtractValueInst(EVI->getAggregateOperand(),
|
||||||
|
EVI->getIndices(), DL, TLI, DT, AC, I);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Instruction::PHI:
|
case Instruction::PHI:
|
||||||
Result = SimplifyPHINode(cast<PHINode>(I), Query(DL, TLI, DT, AC, I));
|
Result = SimplifyPHINode(cast<PHINode>(I), Query(DL, TLI, DT, AC, I));
|
||||||
break;
|
break;
|
||||||
|
@ -2174,16 +2174,9 @@ Instruction *InstCombiner::visitExtractValueInst(ExtractValueInst &EV) {
|
|||||||
if (!EV.hasIndices())
|
if (!EV.hasIndices())
|
||||||
return ReplaceInstUsesWith(EV, Agg);
|
return ReplaceInstUsesWith(EV, Agg);
|
||||||
|
|
||||||
if (Constant *C = dyn_cast<Constant>(Agg)) {
|
if (Value *V =
|
||||||
if (Constant *C2 = C->getAggregateElement(*EV.idx_begin())) {
|
SimplifyExtractValueInst(Agg, EV.getIndices(), DL, TLI, DT, AC))
|
||||||
if (EV.getNumIndices() == 0)
|
return ReplaceInstUsesWith(EV, V);
|
||||||
return ReplaceInstUsesWith(EV, C2);
|
|
||||||
// Extract the remaining indices out of the constant indexed by the
|
|
||||||
// first index
|
|
||||||
return ExtractValueInst::Create(C2, EV.getIndices().slice(1));
|
|
||||||
}
|
|
||||||
return nullptr; // Can't handle other constants
|
|
||||||
}
|
|
||||||
|
|
||||||
if (InsertValueInst *IV = dyn_cast<InsertValueInst>(Agg)) {
|
if (InsertValueInst *IV = dyn_cast<InsertValueInst>(Agg)) {
|
||||||
// We're extracting from an insertvalue instruction, compare the indices
|
// We're extracting from an insertvalue instruction, compare the indices
|
||||||
|
@ -27,3 +27,12 @@ define { i8, i32 } @test2({ i8*, i32 } %x) {
|
|||||||
ret { i8, i32 } %ins
|
ret { i8, i32 } %ins
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i32 @test3(i32 %a, float %b) {
|
||||||
|
%agg1 = insertvalue {i32, float} undef, i32 %a, 0
|
||||||
|
%agg2 = insertvalue {i32, float} %agg1, float %b, 1
|
||||||
|
%ev = extractvalue {i32, float} %agg2, 0
|
||||||
|
ret i32 %ev
|
||||||
|
; CHECK-LABEL: @test3(
|
||||||
|
; CHECK: ret i32 %a
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user