Skip to content

Commit fe2d8d5

Browse files
committed
[SIL] Get access to LLVM intrinsic attributes.
And use them to decide if an llvm intrinsic apply instruction can be considered dead. (This is a hack because it uses LLVM Global context. However, we already use this approach elsewhere.) Swift SVN r7404
1 parent eda2203 commit fe2d8d5

File tree

3 files changed

+18
-42
lines changed

3 files changed

+18
-42
lines changed

include/swift/AST/Builtins.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "swift/Basic/LLVM.h"
2121
#include "llvm/ADT/SmallVector.h"
22+
#include "llvm/IR/Attributes.h"
2223
#include "swift/AST/Type.h"
2324
#include "llvm/IR/Intrinsics.h"
2425
#include "llvm/Support/ErrorHandling.h"
@@ -96,6 +97,7 @@ struct BuiltinInfo {
9697
struct IntrinsicInfo {
9798
llvm::Intrinsic::ID ID;
9899
SmallVector<Type, 4> Types;
100+
bool hasAttribute(llvm::Attribute::AttrKind Kind) const;
99101
};
100102

101103
}

lib/AST/Builtins.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ bool BuiltinInfo::isReadNone() const {
3939
return strchr(BuiltinExtraInfo[(unsigned)ID].Attributes, 'n') != 0;
4040
}
4141

42+
bool IntrinsicInfo::hasAttribute(llvm::Attribute::AttrKind Kind) const {
43+
// FIXME: We should not be relying on the global LLVM context.
44+
llvm::AttributeSet attrs
45+
= llvm::Intrinsic::getAttributes(llvm::getGlobalContext(), ID);
46+
return (attrs.hasAttribute(llvm::AttributeSet::FunctionIndex, Kind));
47+
}
48+
4249
Type swift::getBuiltinType(ASTContext &Context, StringRef Name) {
4350
// Vectors are VecNxT, where "N" is the number of elements and
4451
// T is the element type.

lib/SILPasses/Utils/Local.cpp

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -17,51 +17,19 @@ using namespace swift;
1717
static bool isSideEffectFree(BuiltinFunctionRefInst *FR) {
1818

1919
// First, check if we are dealing with a swift builtin.
20-
const BuiltinInfo &Info = FR->getBuiltinInfo();
21-
if (Info.ID != BuiltinValueKind::None) {
22-
return Info.isReadNone();
20+
const BuiltinInfo &BInfo = FR->getBuiltinInfo();
21+
if (BInfo.ID != BuiltinValueKind::None) {
22+
return BInfo.isReadNone();
2323
}
2424

2525
// Second, specialcase llvm intrinsic.
26-
// FIXME: This list might not be complete. Would be good to derive this
27-
// info from llvm.
28-
switch (FR->getIntrinsicInfo().ID) {
29-
default:
30-
return false;
31-
case llvm::Intrinsic::fabs:
32-
case llvm::Intrinsic::log:
33-
case llvm::Intrinsic::log2:
34-
case llvm::Intrinsic::log10:
35-
case llvm::Intrinsic::exp:
36-
case llvm::Intrinsic::exp2:
37-
case llvm::Intrinsic::floor:
38-
case llvm::Intrinsic::sqrt:
39-
case llvm::Intrinsic::pow:
40-
case llvm::Intrinsic::powi:
41-
case llvm::Intrinsic::bswap:
42-
case llvm::Intrinsic::ctpop:
43-
case llvm::Intrinsic::ctlz:
44-
case llvm::Intrinsic::cttz:
45-
case llvm::Intrinsic::sadd_with_overflow:
46-
case llvm::Intrinsic::uadd_with_overflow:
47-
case llvm::Intrinsic::ssub_with_overflow:
48-
case llvm::Intrinsic::usub_with_overflow:
49-
case llvm::Intrinsic::smul_with_overflow:
50-
case llvm::Intrinsic::umul_with_overflow:
51-
case llvm::Intrinsic::convert_from_fp16:
52-
case llvm::Intrinsic::convert_to_fp16:
53-
case llvm::Intrinsic::x86_sse_cvtss2si:
54-
case llvm::Intrinsic::x86_sse_cvtss2si64:
55-
case llvm::Intrinsic::x86_sse_cvttss2si:
56-
case llvm::Intrinsic::x86_sse_cvttss2si64:
57-
case llvm::Intrinsic::x86_sse2_cvtsd2si:
58-
case llvm::Intrinsic::x86_sse2_cvtsd2si64:
59-
case llvm::Intrinsic::x86_sse2_cvttsd2si:
60-
case llvm::Intrinsic::x86_sse2_cvttsd2si64:
61-
return true;
26+
const IntrinsicInfo & IInfo = FR->getIntrinsicInfo();
27+
if (IInfo.ID != llvm::Intrinsic::not_intrinsic) {
28+
return ( (IInfo.hasAttribute(llvm::Attribute::ReadNone) ||
29+
IInfo.hasAttribute(llvm::Attribute::ReadOnly)) &&
30+
IInfo.hasAttribute(llvm::Attribute::NoUnwind) );
6231
}
6332

64-
// FIXME: Special handling of LLVM IR instructions.
6533
llvm_unreachable("All cases are covered.");
6634
}
6735

@@ -76,8 +44,7 @@ static bool isInstructionTriviallyDead(SILInstruction *I) {
7644
if (const ApplyInst *AI = dyn_cast<ApplyInst>(I)) {
7745
if (BuiltinFunctionRefInst *FR =
7846
dyn_cast<BuiltinFunctionRefInst>(AI->getCallee().getDef())) {
79-
if (isSideEffectFree(FR))
80-
return true;
47+
return isSideEffectFree(FR);
8148
}
8249
}
8350

0 commit comments

Comments
 (0)