mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
SIL: Move SILGen and passes over to use "builtin" instead of "apply (builtin_function_ref)".
Swift SVN r22785
This commit is contained in:
@@ -44,14 +44,13 @@ namespace {
|
||||
SILValue visitUncheckedAddrCastInst(UncheckedAddrCastInst *UACI);
|
||||
SILValue visitStructInst(StructInst *SI);
|
||||
SILValue visitTupleInst(TupleInst *SI);
|
||||
SILValue visitApplyInst(ApplyInst *AI);
|
||||
SILValue visitBuiltinInst(BuiltinInst *AI);
|
||||
SILValue visitUpcastInst(UpcastInst *UI);
|
||||
SILValue visitUncheckedRefBitCastInst(UncheckedRefBitCastInst *URBCI);
|
||||
SILValue
|
||||
visitUncheckedTrivialBitCastInst(UncheckedTrivialBitCastInst *UTBCI);
|
||||
|
||||
SILValue simplifyOverflowBuiltin(ApplyInst *AI,
|
||||
BuiltinFunctionRefInst *FR);
|
||||
SILValue simplifyOverflowBuiltin(BuiltinInst *BI);
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@@ -133,9 +132,8 @@ SILValue InstSimplifier::visitTupleExtractInst(TupleExtractInst *TEI) {
|
||||
// tuple_extract(apply([add|sub|...]overflow(x,y)), 0) -> x
|
||||
// tuple_extract(apply(checked_trunc(ext(x))), 0) -> x
|
||||
if (TEI->getFieldNo() == 0)
|
||||
if (ApplyInst *AI = dyn_cast<ApplyInst>(TEI->getOperand()))
|
||||
if (auto *BFRI = dyn_cast<BuiltinFunctionRefInst>(AI->getCallee()))
|
||||
return simplifyOverflowBuiltin(AI, BFRI);
|
||||
if (BuiltinInst *BI = dyn_cast<BuiltinInst>(TEI->getOperand()))
|
||||
return simplifyOverflowBuiltin(BI);
|
||||
|
||||
return SILValue();
|
||||
}
|
||||
@@ -341,9 +339,8 @@ visitUncheckedTrivialBitCastInst(UncheckedTrivialBitCastInst *UTBCI) {
|
||||
}
|
||||
|
||||
|
||||
static SILValue simplifyBuiltin(ApplyInst *AI,
|
||||
BuiltinFunctionRefInst *FR) {
|
||||
const IntrinsicInfo &Intrinsic = FR->getIntrinsicInfo();
|
||||
static SILValue simplifyBuiltin(BuiltinInst *BI) {
|
||||
const IntrinsicInfo &Intrinsic = BI->getIntrinsicInfo();
|
||||
|
||||
switch (Intrinsic.ID) {
|
||||
default:
|
||||
@@ -356,14 +353,14 @@ static SILValue simplifyBuiltin(ApplyInst *AI,
|
||||
// there is nothing left to expect so propagate the input, i.e.,
|
||||
//
|
||||
// apply(expect, constant, _) -> constant.
|
||||
if (auto *Literal = dyn_cast<IntegerLiteralInst>(AI->getArgument(0)))
|
||||
if (auto *Literal = dyn_cast<IntegerLiteralInst>(BI->getArguments()[0]))
|
||||
return Literal;
|
||||
return SILValue();
|
||||
}
|
||||
|
||||
// Otherwise, it should be one of the builtin functions.
|
||||
OperandValueArrayRef Args = AI->getArguments();
|
||||
const BuiltinInfo &Builtin = FR->getBuiltinInfo();
|
||||
OperandValueArrayRef Args = BI->getArguments();
|
||||
const BuiltinInfo &Builtin = BI->getBuiltinInfo();
|
||||
|
||||
switch (Builtin.ID) {
|
||||
default: break;
|
||||
@@ -374,7 +371,7 @@ static SILValue simplifyBuiltin(ApplyInst *AI,
|
||||
// trunc(extOrBitCast(x)) -> x
|
||||
if (match(Op, m_ExtOrBitCast(m_SILValue(Result)))) {
|
||||
// Truncated back to the same bits we started with.
|
||||
if (Result.getType() == AI->getType())
|
||||
if (Result.getType() == BI->getType())
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -384,7 +381,7 @@ static SILValue simplifyBuiltin(ApplyInst *AI,
|
||||
m_ExtOrBitCast(m_SILValue(Result))), 0))) {
|
||||
// If the top bit of Result is known to be 0, then
|
||||
// it is safe to replace the whole patterb by original bits of x
|
||||
if (Result.getType() == AI->getType()) {
|
||||
if (Result.getType() == BI->getType()) {
|
||||
if (auto signBit = computeSignBit(Result))
|
||||
if (!signBit.getValue())
|
||||
return Result;
|
||||
@@ -398,11 +395,8 @@ static SILValue simplifyBuiltin(ApplyInst *AI,
|
||||
|
||||
/// Simplify an apply of the builtin canBeClass to either 0 or 1
|
||||
/// when we can statically determine the result.
|
||||
SILValue InstSimplifier::visitApplyInst(ApplyInst *AI) {
|
||||
auto *BFRI = dyn_cast<BuiltinFunctionRefInst>(AI->getCallee());
|
||||
if (BFRI)
|
||||
return simplifyBuiltin(AI, BFRI);
|
||||
return SILValue();
|
||||
SILValue InstSimplifier::visitBuiltinInst(BuiltinInst *BI) {
|
||||
return simplifyBuiltin(BI);
|
||||
}
|
||||
|
||||
/// \brief Simplify arithmetic intrinsics with overflow and known identity
|
||||
@@ -410,9 +404,9 @@ SILValue InstSimplifier::visitApplyInst(ApplyInst *AI) {
|
||||
/// If this returns a value other than SILValue() then the instruction was
|
||||
/// simplified to a value which doesn't overflow. The overflow case is handled
|
||||
/// in SILCombine.
|
||||
static SILValue simplifyBinaryWithOverflow(ApplyInst *AI,
|
||||
static SILValue simplifyBinaryWithOverflow(BuiltinInst *BI,
|
||||
llvm::Intrinsic::ID ID) {
|
||||
OperandValueArrayRef Args = AI->getArguments();
|
||||
OperandValueArrayRef Args = BI->getArguments();
|
||||
assert(Args.size() >= 2);
|
||||
|
||||
const SILValue &Op1 = Args[0];
|
||||
@@ -470,9 +464,8 @@ static SILValue simplifyBinaryWithOverflow(ApplyInst *AI,
|
||||
/// is OK, because this function is invoked only internally when processing
|
||||
/// tuple_extract instructions. Therefore the result of this function
|
||||
/// is used for simplifications like tuple_extract(x, 0) -> simplified(x)
|
||||
SILValue InstSimplifier::simplifyOverflowBuiltin(ApplyInst *AI,
|
||||
BuiltinFunctionRefInst *FR) {
|
||||
const IntrinsicInfo &Intrinsic = FR->getIntrinsicInfo();
|
||||
SILValue InstSimplifier::simplifyOverflowBuiltin(BuiltinInst *BI) {
|
||||
const IntrinsicInfo &Intrinsic = BI->getIntrinsicInfo();
|
||||
|
||||
// If it's an llvm intrinsic, fold the intrinsic.
|
||||
switch (Intrinsic.ID) {
|
||||
@@ -486,26 +479,26 @@ SILValue InstSimplifier::simplifyOverflowBuiltin(ApplyInst *AI,
|
||||
case llvm::Intrinsic::usub_with_overflow:
|
||||
case llvm::Intrinsic::smul_with_overflow:
|
||||
case llvm::Intrinsic::umul_with_overflow:
|
||||
return simplifyBinaryWithOverflow(AI, Intrinsic.ID);
|
||||
return simplifyBinaryWithOverflow(BI, Intrinsic.ID);
|
||||
}
|
||||
|
||||
// Otherwise, it should be one of the builtin functions.
|
||||
const BuiltinInfo &Builtin = FR->getBuiltinInfo();
|
||||
const BuiltinInfo &Builtin = BI->getBuiltinInfo();
|
||||
|
||||
switch (Builtin.ID) {
|
||||
default: break;
|
||||
|
||||
case BuiltinValueKind::SUCheckedConversion:
|
||||
case BuiltinValueKind::USCheckedConversion: {
|
||||
OperandValueArrayRef Args = AI->getArguments();
|
||||
OperandValueArrayRef Args = BI->getArguments();
|
||||
const SILValue &Op = Args[0];
|
||||
if (auto signBit = computeSignBit(Op))
|
||||
if (!signBit.getValue())
|
||||
return Op;
|
||||
SILValue Result;
|
||||
// CheckedConversion(ExtOrBitCast(x)) -> x
|
||||
if (match(AI, m_CheckedConversion(m_ExtOrBitCast(m_SILValue(Result)))))
|
||||
if (Result.getType() == AI->getType().getTupleElementType(0)) {
|
||||
if (match(BI, m_CheckedConversion(m_ExtOrBitCast(m_SILValue(Result)))))
|
||||
if (Result.getType() == BI->getType().getTupleElementType(0)) {
|
||||
assert (!computeSignBit(Result).getValue() && "Sign bit should be 0");
|
||||
return Result;
|
||||
}
|
||||
@@ -518,8 +511,8 @@ SILValue InstSimplifier::simplifyOverflowBuiltin(ApplyInst *AI,
|
||||
case BuiltinValueKind::SToSCheckedTrunc: {
|
||||
SILValue Result;
|
||||
// CheckedTrunc(Ext(x)) -> x
|
||||
if (match(AI, m_CheckedTrunc(m_Ext(m_SILValue(Result)))))
|
||||
if (Result.getType() == AI->getType().getTupleElementType(0))
|
||||
if (match(BI, m_CheckedTrunc(m_Ext(m_SILValue(Result)))))
|
||||
if (Result.getType() == BI->getType().getTupleElementType(0))
|
||||
if (auto signBit = computeSignBit(Result))
|
||||
if (!signBit.getValue())
|
||||
return Result;
|
||||
@@ -531,7 +524,7 @@ SILValue InstSimplifier::simplifyOverflowBuiltin(ApplyInst *AI,
|
||||
#define BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(id, name, _, attrs, overload) \
|
||||
case BuiltinValueKind::id:
|
||||
#include "swift/AST/Builtins.def"
|
||||
return simplifyBinaryWithOverflow(AI,
|
||||
return simplifyBinaryWithOverflow(BI,
|
||||
getLLVMIntrinsicIDForBuiltinWithOverflow(Builtin.ID));
|
||||
|
||||
}
|
||||
@@ -555,8 +548,6 @@ SILValue swift::simplifyInstruction(SILInstruction *I) {
|
||||
/// no overflow. Therefore the overflow flag is known to have a value of 0 if
|
||||
/// simplification was successful.
|
||||
/// In case when a simplification is not possible, a null SILValue is returned.
|
||||
SILValue swift::simplifyOverflowBuiltinInstruction(ApplyInst *AI) {
|
||||
if (auto *BFRI = dyn_cast<BuiltinFunctionRefInst>(AI->getCallee()))
|
||||
return InstSimplifier().simplifyOverflowBuiltin(AI, BFRI);
|
||||
return SILValue();
|
||||
SILValue swift::simplifyOverflowBuiltinInstruction(BuiltinInst *BI) {
|
||||
return InstSimplifier().simplifyOverflowBuiltin(BI);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user