Skip to content

Commit

Permalink
[IR] Remove support for extractvalue constant expression
Browse files Browse the repository at this point in the history
This removes the extractvalue constant expression, as part of
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179.
extractvalue is already not supported in bitcode, so we do not need
to worry about bitcode auto-upgrade.

Uses of ConstantExpr::getExtractValue() should be replaced with
IRBuilder::CreateExtractValue() (if the fact that the result is
constant is not important) or ConstantFoldExtractValueInstruction()
(if it is). Though for this particular case, it is also possible
and usually preferable to use getAggregateElement() instead.

The C API function LLVMConstExtractValue() is removed, as the
underlying constant expression no longer exists. Instead,
LLVMBuildExtractValue() should be used (which will constant fold
or create an instruction). Depending on the use-case,
LLVMGetAggregateElement() may also be used instead.

Differential Revision: https://reviews.llvm.org/D125795
  • Loading branch information
nikic committed Jun 28, 2022
1 parent ab72182 commit 5548e80
Show file tree
Hide file tree
Showing 26 changed files with 61 additions and 179 deletions.
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/ItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,7 @@ ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E,
adj = llvm::ConstantInt::get(adj->getType(), offset);
}

llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1);
llvm::Constant *srcAdj = src->getAggregateElement(1);
llvm::Constant *dstAdj;
if (isDerivedToBase)
dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
Expand Down
14 changes: 0 additions & 14 deletions llvm/bindings/go/llvm/ir.go
Original file line number Diff line number Diff line change
Expand Up @@ -993,20 +993,6 @@ func ConstShuffleVector(veca, vecb, mask Value) (rv Value) {
return
}

//TODO
//LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList,
// unsigned NumIdx);

func ConstExtractValue(agg Value, indices []uint32) (rv Value) {
n := len(indices)
if n == 0 {
panic("one or more indices are required")
}
ptr := (*C.unsigned)(&indices[0])
rv.C = C.LLVMConstExtractValue(agg.C, ptr, C.unsigned(n))
return
}

func ConstInsertValue(agg, val Value, indices []uint32) (rv Value) {
n := len(indices)
if n == 0 {
Expand Down
2 changes: 0 additions & 2 deletions llvm/bindings/ocaml/llvm/llvm.ml
Original file line number Diff line number Diff line change
Expand Up @@ -704,8 +704,6 @@ external const_insertelement : llvalue -> llvalue -> llvalue -> llvalue
= "LLVMConstInsertElement"
external const_shufflevector : llvalue -> llvalue -> llvalue -> llvalue
= "LLVMConstShuffleVector"
external const_extractvalue : llvalue -> int array -> llvalue
= "llvm_const_extractvalue"
external const_insertvalue : llvalue -> llvalue -> int array -> llvalue
= "llvm_const_insertvalue"
external const_inline_asm : lltype -> string -> string -> bool -> bool ->
Expand Down
5 changes: 0 additions & 5 deletions llvm/bindings/ocaml/llvm/llvm.mli
Original file line number Diff line number Diff line change
Expand Up @@ -1347,11 +1347,6 @@ val const_insertelement : llvalue -> llvalue -> llvalue -> llvalue
See the method [llvm::ConstantExpr::getShuffleVector]. *)
val const_shufflevector : llvalue -> llvalue -> llvalue -> llvalue

(** [const_extractvalue agg idxs] returns the constant [idxs]th value of
constant aggregate [agg]. Each [idxs] must be less than the size of the
aggregate. See the method [llvm::ConstantExpr::getExtractValue]. *)
val const_extractvalue : llvalue -> int array -> llvalue

(** [const_insertvalue agg val idxs] inserts the value [val] in the specified
indexs [idxs] in the aggregate [agg]. Each [idxs] must be less than the size
of the aggregate. See the method [llvm::ConstantExpr::getInsertValue]. *)
Expand Down
16 changes: 0 additions & 16 deletions llvm/bindings/ocaml/llvm/llvm_ocaml.c
Original file line number Diff line number Diff line change
Expand Up @@ -1013,22 +1013,6 @@ LLVMValueRef llvm_const_intcast(LLVMValueRef CV, LLVMTypeRef T,
return LLVMConstIntCast(CV, T, Bool_val(IsSigned));
}

/* llvalue -> int array -> llvalue */
LLVMValueRef llvm_const_extractvalue(LLVMValueRef Aggregate, value Indices) {
int size = Wosize_val(Indices);
int i;
LLVMValueRef result;

unsigned *idxs = (unsigned *)malloc(size * sizeof(unsigned));
for (i = 0; i < size; i++) {
idxs[i] = Int_val(Field(Indices, i));
}

result = LLVMConstExtractValue(Aggregate, idxs, size);
free(idxs);
return result;
}

/* llvalue -> llvalue -> int array -> llvalue */
LLVMValueRef llvm_const_insertvalue(LLVMValueRef Aggregate, LLVMValueRef Val,
value Indices) {
Expand Down
9 changes: 9 additions & 0 deletions llvm/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ Changes to the LLVM IR

* Renamed ``llvm.experimental.vector.extract`` intrinsic to ``llvm.vector.extract``.
* Renamed ``llvm.experimental.vector.insert`` intrinsic to ``llvm.vector.insert``.
* The constant expression variants of the following instructions have been
removed:
* ``extractvalue``

Changes to building LLVM
------------------------
Expand Down Expand Up @@ -171,6 +174,12 @@ Changes to the C API
favor of the new function, which works on all constant aggregates, rather than
only instances of ``ConstantDataSequential``.

* The following functions for creating constant expressions have been removed,
because the underlying constant expressions are no longer supported. Instead,
an instruction should be created using the ``LLVMBuildXYZ`` APIs, which will
constant fold the operands if possible and create an instruction otherwise:
* ``LLVMConstExtractValue``

Changes to the Go bindings
--------------------------

Expand Down
2 changes: 0 additions & 2 deletions llvm/include/llvm-c/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -2238,8 +2238,6 @@ LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant,
LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant,
LLVMValueRef VectorBConstant,
LLVMValueRef MaskConstant);
LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList,
unsigned NumIdx);
LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant,
LLVMValueRef ElementValueConstant,
unsigned *IdxList, unsigned NumIdx);
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Analysis/TargetFolder.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class TargetFolder final : public IRBuilderFolder {
Value *FoldExtractValue(Value *Agg,
ArrayRef<unsigned> IdxList) const override {
if (auto *CAgg = dyn_cast<Constant>(Agg))
return Fold(ConstantExpr::getExtractValue(CAgg, IdxList));
return ConstantFoldExtractValueInstruction(CAgg, IdxList);
return nullptr;
};

Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/IR/ConstantFolder.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/ConstantFold.h"
#include "llvm/IR/IRBuilderFolder.h"
#include "llvm/IR/Instruction.h"

Expand Down Expand Up @@ -97,7 +98,7 @@ class ConstantFolder final : public IRBuilderFolder {
Value *FoldExtractValue(Value *Agg,
ArrayRef<unsigned> IdxList) const override {
if (auto *CAgg = dyn_cast<Constant>(Agg))
return ConstantExpr::getExtractValue(CAgg, IdxList);
return ConstantFoldExtractValueInstruction(CAgg, IdxList);
return nullptr;
};

Expand Down
2 changes: 0 additions & 2 deletions llvm/include/llvm/IR/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,8 +1294,6 @@ class ConstantExpr : public Constant {
static Constant *getShuffleVector(Constant *V1, Constant *V2,
ArrayRef<int> Mask,
Type *OnlyIfReducedTy = nullptr);
static Constant *getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs,
Type *OnlyIfReducedTy = nullptr);
static Constant *getInsertValue(Constant *Agg, Constant *Val,
ArrayRef<unsigned> Idxs,
Type *OnlyIfReducedTy = nullptr);
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Analysis/ConstantFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1082,7 +1082,7 @@ Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, unsigned Opcode,
case Instruction::ExtractElement:
return ConstantExpr::getExtractElement(Ops[0], Ops[1]);
case Instruction::ExtractValue:
return ConstantExpr::getExtractValue(
return ConstantFoldExtractValueInstruction(
Ops[0], cast<ExtractValueInst>(InstOrCE)->getIndices());
case Instruction::InsertElement:
return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]);
Expand Down Expand Up @@ -1198,7 +1198,7 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const DataLayout &DL,
return ConstantExpr::getInsertValue(Ops[0], Ops[1], IVI->getIndices());

if (auto *EVI = dyn_cast<ExtractValueInst>(I))
return ConstantExpr::getExtractValue(Ops[0], EVI->getIndices());
return ConstantFoldExtractValueInstruction(Ops[0], EVI->getIndices());

return ConstantFoldInstOperands(I, Ops, DL, TLI);
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Analysis/InlineCost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2078,7 +2078,7 @@ bool CallAnalyzer::visitStore(StoreInst &I) {
bool CallAnalyzer::visitExtractValue(ExtractValueInst &I) {
// Constant folding for extract value is trivial.
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
return ConstantExpr::getExtractValue(COps[0], I.getIndices());
return ConstantFoldExtractValueInstruction(COps[0], I.getIndices());
}))
return true;

Expand Down
20 changes: 2 additions & 18 deletions llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3472,24 +3472,8 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
ID.Kind = ValID::t_Constant;
return false;
}
case lltok::kw_extractvalue: {
Lex.Lex();
Constant *Val;
SmallVector<unsigned, 4> Indices;
if (parseToken(lltok::lparen,
"expected '(' in extractvalue constantexpr") ||
parseGlobalTypeAndValue(Val) || parseIndexList(Indices) ||
parseToken(lltok::rparen, "expected ')' in extractvalue constantexpr"))
return true;

if (!Val->getType()->isAggregateType())
return error(ID.Loc, "extractvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices))
return error(ID.Loc, "invalid indices for extractvalue");
ID.ConstantVal = ConstantExpr::getExtractValue(Val, Indices);
ID.Kind = ValID::t_Constant;
return false;
}
case lltok::kw_extractvalue:
return error(ID.Loc, "extractvalue constexprs are no longer supported");
case lltok::kw_insertvalue: {
Lex.Lex();
Constant *Val0, *Val1;
Expand Down
37 changes: 1 addition & 36 deletions llvm/lib/IR/Constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,8 +547,6 @@ void llvm::deleteConstant(Constant *C) {
delete static_cast<InsertElementConstantExpr *>(C);
else if (isa<ShuffleVectorConstantExpr>(C))
delete static_cast<ShuffleVectorConstantExpr *>(C);
else if (isa<ExtractValueConstantExpr>(C))
delete static_cast<ExtractValueConstantExpr *>(C);
else if (isa<InsertValueConstantExpr>(C))
delete static_cast<InsertValueConstantExpr *>(C);
else if (isa<GetElementPtrConstantExpr>(C))
Expand Down Expand Up @@ -1491,15 +1489,10 @@ bool ConstantExpr::isCompare() const {
}

bool ConstantExpr::hasIndices() const {
return getOpcode() == Instruction::ExtractValue ||
getOpcode() == Instruction::InsertValue;
return getOpcode() == Instruction::InsertValue;
}

ArrayRef<unsigned> ConstantExpr::getIndices() const {
if (const ExtractValueConstantExpr *EVCE =
dyn_cast<ExtractValueConstantExpr>(this))
return EVCE->Indices;

return cast<InsertValueConstantExpr>(this)->Indices;
}

Expand Down Expand Up @@ -1549,8 +1542,6 @@ Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
case Instruction::InsertValue:
return ConstantExpr::getInsertValue(Ops[0], Ops[1], getIndices(),
OnlyIfReducedTy);
case Instruction::ExtractValue:
return ConstantExpr::getExtractValue(Ops[0], getIndices(), OnlyIfReducedTy);
case Instruction::FNeg:
return ConstantExpr::getFNeg(Ops[0]);
case Instruction::ShuffleVector:
Expand Down Expand Up @@ -2677,30 +2668,6 @@ Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val,
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}

Constant *ConstantExpr::getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs,
Type *OnlyIfReducedTy) {
assert(Agg->getType()->isFirstClassType() &&
"Tried to create extractelement operation on non-first-class type!");

Type *ReqTy = ExtractValueInst::getIndexedType(Agg->getType(), Idxs);
(void)ReqTy;
assert(ReqTy && "extractvalue indices invalid!");

assert(Agg->getType()->isFirstClassType() &&
"Non-first-class type for constant extractvalue expression");
if (Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs))
return FC;

if (OnlyIfReducedTy == ReqTy)
return nullptr;

Constant *ArgVec[] = { Agg };
const ConstantExprKeyType Key(Instruction::ExtractValue, ArgVec, 0, 0, Idxs);

LLVMContextImpl *pImpl = Agg->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}

Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) {
assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NEG a nonintegral value!");
Expand Down Expand Up @@ -3553,8 +3520,6 @@ Instruction *ConstantExpr::getAsInstruction(Instruction *InsertBefore) const {
case Instruction::InsertValue:
return InsertValueInst::Create(Ops[0], Ops[1], getIndices(), "",
InsertBefore);
case Instruction::ExtractValue:
return ExtractValueInst::Create(Ops[0], getIndices(), "", InsertBefore);
case Instruction::ShuffleVector:
return new ShuffleVectorInst(Ops[0], Ops[1], getShuffleMask(), "",
InsertBefore);
Expand Down
37 changes: 0 additions & 37 deletions llvm/lib/IR/ConstantsContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,36 +209,6 @@ class ShuffleVectorConstantExpr final : public ConstantExpr {
}
};

/// ExtractValueConstantExpr - This class is private to
/// Constants.cpp, and is used behind the scenes to implement
/// extractvalue constant exprs.
class ExtractValueConstantExpr final : public ConstantExpr {
public:
ExtractValueConstantExpr(Constant *Agg, ArrayRef<unsigned> IdxList,
Type *DestTy)
: ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1),
Indices(IdxList.begin(), IdxList.end()) {
Op<0>() = Agg;
}

// allocate space for exactly one operand
void *operator new(size_t S) { return User::operator new(S, 1); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }

/// Indices - These identify which value to extract.
const SmallVector<unsigned, 4> Indices;

/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);

static bool classof(const ConstantExpr *CE) {
return CE->getOpcode() == Instruction::ExtractValue;
}
static bool classof(const Value *V) {
return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
}
};

/// InsertValueConstantExpr - This class is private to
/// Constants.cpp, and is used behind the scenes to implement
/// insertvalue constant exprs.
Expand Down Expand Up @@ -362,11 +332,6 @@ struct OperandTraits<ShuffleVectorConstantExpr>
: public FixedNumOperandTraits<ShuffleVectorConstantExpr, 2> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)

template <>
struct OperandTraits<ExtractValueConstantExpr>
: public FixedNumOperandTraits<ExtractValueConstantExpr, 1> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value)

template <>
struct OperandTraits<InsertValueConstantExpr>
: public FixedNumOperandTraits<InsertValueConstantExpr, 2> {};
Expand Down Expand Up @@ -620,8 +585,6 @@ struct ConstantExprKeyType {
return new ShuffleVectorConstantExpr(Ops[0], Ops[1], ShuffleMask);
case Instruction::InsertValue:
return new InsertValueConstantExpr(Ops[0], Ops[1], Indexes, Ty);
case Instruction::ExtractValue:
return new ExtractValueConstantExpr(Ops[0], Indexes, Ty);
case Instruction::GetElementPtr:
return GetElementPtrConstantExpr::Create(ExplicitTy, Ops[0], Ops.slice(1),
Ty, SubclassOptionalData);
Expand Down
6 changes: 0 additions & 6 deletions llvm/lib/IR/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1875,12 +1875,6 @@ LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant,
IntMask));
}

LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList,
unsigned NumIdx) {
return wrap(ConstantExpr::getExtractValue(unwrap<Constant>(AggConstant),
makeArrayRef(IdxList, NumIdx)));
}

LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant,
LLVMValueRef ElementValueConstant,
unsigned *IdxList, unsigned NumIdx) {
Expand Down
5 changes: 2 additions & 3 deletions llvm/lib/Transforms/Coroutines/CoroElide.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,14 +336,13 @@ bool Lowerer::processCoroId(CoroIdInst *CoroId, AAResults &AA,
assert(Resumers && "PostSplit coro.id Info argument must refer to an array"
"of coroutine subfunctions");
auto *ResumeAddrConstant =
ConstantExpr::getExtractValue(Resumers, CoroSubFnInst::ResumeIndex);
Resumers->getAggregateElement(CoroSubFnInst::ResumeIndex);

replaceWithConstant(ResumeAddrConstant, ResumeAddr);

bool ShouldElide = shouldElide(CoroId->getFunction(), DT);

auto *DestroyAddrConstant = ConstantExpr::getExtractValue(
Resumers,
auto *DestroyAddrConstant = Resumers->getAggregateElement(
ShouldElide ? CoroSubFnInst::CleanupIndex : CoroSubFnInst::DestroyIndex);

for (auto &It : DestroyAddr)
Expand Down
7 changes: 5 additions & 2 deletions llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,11 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
if (!Elt) return nullptr;

// If this is indexing an array of structures, get the structure element.
if (!LaterIndices.empty())
Elt = ConstantExpr::getExtractValue(Elt, LaterIndices);
if (!LaterIndices.empty()) {
Elt = ConstantFoldExtractValueInstruction(Elt, LaterIndices);
if (!Elt)
return nullptr;
}

// If the element is masked, handle it.
if (AndCst) Elt = ConstantExpr::getAnd(Elt, AndCst);
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Transforms/Utils/Evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,10 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB,
LLVM_DEBUG(dbgs() << "Found a Select! Simplifying: " << *InstResult
<< "\n");
} else if (auto *EVI = dyn_cast<ExtractValueInst>(CurInst)) {
InstResult = ConstantExpr::getExtractValue(
InstResult = ConstantFoldExtractValueInstruction(
getVal(EVI->getAggregateOperand()), EVI->getIndices());
if (!InstResult)
return false;
LLVM_DEBUG(dbgs() << "Found an ExtractValueInst! Simplifying: "
<< *InstResult << "\n");
} else if (auto *IVI = dyn_cast<InsertValueInst>(CurInst)) {
Expand Down
Loading

0 comments on commit 5548e80

Please sign in to comment.