[SIL] Cache Builtin Kind and type lookup in SILModule and speed up CCP

Swift SVN r7354
This commit is contained in:
Anna Zaks
2013-08-20 01:31:48 +00:00
parent b0dd877454
commit 2870c53a54
4 changed files with 44 additions and 17 deletions

View File

@@ -18,12 +18,13 @@
#define SWIFT_AST_BUILTINS_H
#include "swift/Basic/LLVM.h"
#include "llvm/ADT/SmallVector.h"
#include "swift/AST/Type.h"
#include "llvm/Support/ErrorHandling.h"
namespace swift {
class ASTContext;
class Identifier;
class Type;
class ValueDecl;
/// Get the builtin type for the given name.
@@ -83,6 +84,12 @@ enum class BuiltinValueKind {
#include "swift/AST/Builtins.def"
};
/// \brief The information identifying the builtin - it's kind and types.
struct BuiltinInfo {
BuiltinValueKind ID;
SmallVector<Type, 4> Types;
};
}
#endif

View File

@@ -18,6 +18,7 @@
#define SWIFT_SIL_SILMODULE_H
#include "swift/AST/ASTContext.h"
#include "swift/AST/Builtins.h"
#include "swift/Basic/LangOptions.h"
#include "swift/Basic/Range.h"
#include "swift/SIL/SILDeclRef.h"
@@ -94,6 +95,9 @@ private:
/// This is a cache of intrinsic Function declarations to numeric ID mappings.
llvm::DenseMap<const FuncDecl*, llvm::Intrinsic::ID> IntrinsicIDCache;
/// This is a cache of builtin Function declarations to numeric ID mappings.
llvm::DenseMap<const FuncDecl*, BuiltinInfo> BuiltinIDCache;
/// The stage of processing this module is at.
SILStage Stage;
@@ -197,6 +201,12 @@ public:
/// intrinsic. The particular intrinsic functions which correspond to the
/// retruned value are defined in llvm/Intrinsics.h.
llvm::Intrinsic::ID getIntrinsicID(const FuncDecl* FD);
/// \brief Looks up the lazily cached identification for the builtin function.
///
/// \returns Returns builtin info of BuiltinValueKind::None kind if the
/// decalation is not a builtin.
const BuiltinInfo &getBuiltinInfo(const FuncDecl* FD);
};
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SILModule &M){

View File

@@ -11,9 +11,10 @@
//===----------------------------------------------------------------------===//
#include "swift/SIL/SILModule.h"
#include "swift/AST/Builtins.h"
#include "swift/SIL/SILValue.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/StringSwitch.h"
using namespace swift;
namespace swift {
@@ -104,4 +105,23 @@ llvm::Intrinsic::ID SILModule::getIntrinsicID(const FuncDecl* FD) {
return IntrinsicIDCache[FD];
}
const BuiltinInfo &SILModule::getBuiltinInfo(const FuncDecl* FD) {
unsigned OldSize = BuiltinIDCache.size();
BuiltinInfo &Info = BuiltinIDCache[FD];
// If the element was not in the cache, lookup the ID and Type.
if (OldSize != BuiltinIDCache.size()) {
// Find the matching ID.
StringRef OperationName = getBuiltinBaseName(getASTContext(),
FD->getName().str(),
Info.Types);
Info.ID = llvm::StringSwitch<BuiltinValueKind>(OperationName)
#define BUILTIN(id, name) \
.Case(name, BuiltinValueKind::id)
#include "swift/AST/Builtins.def"
.Default(BuiltinValueKind::None);
}
return Info;
}

View File

@@ -15,6 +15,7 @@
#include "swift/AST/Builtins.h"
#include "swift/AST/DiagnosticEngine.h"
#include "swift/AST/Diagnostics.h"
#include "swift/AST/Type.h"
#include "swift/Subsystems.h"
#include "swift/SIL/SILBuilder.h"
#include "swift/SILPasses/Utils/Local.h"
@@ -124,20 +125,9 @@ static SILInstruction *constantFoldBuiltin(ApplyInst *AI,
// Otherwise, it should be one of the builin functions.
OperandValueArrayRef Args = AI->getArguments();
SmallVector<Type, 4> Types;
StringRef OperationName = getBuiltinBaseName(M.getASTContext(),
FR->getFunction()->getName().str(),
Types);
const BuiltinInfo &Builtin = M.getBuiltinInfo(FR->getFunction());
// FIXME: Make this faster by introducing a global cache, like in the
// intrinsics case.
BuiltinValueKind BV = llvm::StringSwitch<BuiltinValueKind>(OperationName)
#define BUILTIN(id, name) \
.Case(name, BuiltinValueKind::id)
#include "swift/AST/Builtins.def"
.Default(BuiltinValueKind::None);
switch (BV) {
switch (Builtin.ID) {
default: break;
case BuiltinValueKind::Trunc:
case BuiltinValueKind::ZExt:
@@ -150,10 +140,10 @@ static SILInstruction *constantFoldBuiltin(ApplyInst *AI,
// Get the cast result.
APInt CastResV;
Type DestTy = Types.size() == 2 ? Types[1] : Type();
Type DestTy = Builtin.Types.size() == 2 ? Builtin.Types[1] : Type();
uint32_t DestBitWidth =
DestTy->castTo<BuiltinIntegerType>()->getBitWidth();
switch (BV) {
switch (Builtin.ID) {
default : llvm_unreachable("Invalid case.");
case BuiltinValueKind::Trunc:
CastResV = V->getValue().trunc(DestBitWidth);