Proteus
Programmable JIT compilation and optimization for C/C++ using LLVM
Loading...
Searching...
No Matches
TransformLambdaSpecialization.hpp
Go to the documentation of this file.
1//===-- TransformLambdaSpecialization.hpp -- Specialize arguments --===//
2//
3// Part of the Proteus Project, under the Apache License v2.0 with LLVM
4// Exceptions. See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef PROTEUS_TRANSFORM_LAMBDA_SPECIALIZATION_HPP
12#define PROTEUS_TRANSFORM_LAMBDA_SPECIALIZATION_HPP
13
14#include <llvm/Demangle/Demangle.h>
15#include <llvm/IR/IRBuilder.h>
16#include <llvm/IR/Instructions.h>
17#include <llvm/Support/Casting.h>
18#include <llvm/Support/Debug.h>
19
21#include "proteus/Debug.h"
22#include "proteus/Utils.h"
23
24namespace proteus {
25
26using namespace llvm;
27
28inline Constant *getConstant(LLVMContext &Ctx, Type *ArgType,
29 const RuntimeConstant &RC) {
30 if (ArgType->isIntegerTy(1)) {
31 return ConstantInt::get(ArgType, RC.Value.BoolVal);
32 } else if (ArgType->isIntegerTy(8)) {
33 return ConstantInt::get(ArgType, RC.Value.Int8Val);
34 } else if (ArgType->isIntegerTy(32)) {
35 return ConstantInt::get(ArgType, RC.Value.Int32Val);
36 } else if (ArgType->isIntegerTy(64)) {
37 return ConstantInt::get(ArgType, RC.Value.Int64Val);
38 } else if (ArgType->isFloatTy()) {
39 return ConstantFP::get(ArgType, RC.Value.FloatVal);
40 } else if (ArgType->isDoubleTy()) {
41 return ConstantFP::get(ArgType, RC.Value.DoubleVal);
42 } else if (ArgType->isX86_FP80Ty() || ArgType->isPPC_FP128Ty() ||
43 ArgType->isFP128Ty()) {
44 return ConstantFP::get(ArgType, RC.Value.LongDoubleVal);
45 } else if (ArgType->isPointerTy()) {
46 auto *IntC = ConstantInt::get(Type::getInt64Ty(Ctx), RC.Value.Int64Val);
47 return ConstantExpr::getIntToPtr(IntC, ArgType);
48 } else {
49 std::string TypeString;
50 raw_string_ostream TypeOstream(TypeString);
51 ArgType->print(TypeOstream);
52 PROTEUS_FATAL_ERROR("JIT Incompatible type in runtime constant: " +
53 TypeOstream.str());
54 }
55}
56
58public:
59 static void transform(Module &M, Function &F,
60 const SmallVector<RuntimeConstant> &RCVec) {
61 auto *LambdaClass = F.getArg(0);
62 PROTEUS_DBG(Logger::logs("proteus")
63 << "[LambdaSpec] Function: " << F.getName() << " RCVec size "
64 << RCVec.size() << "\n");
65 PROTEUS_DBG(Logger::logs("proteus")
66 << "TransformLambdaSpecialization::transform" << "\n");
67 PROTEUS_DBG(Logger::logs("proteus") << "\t args" << "\n");
68#if PROTEUS_ENABLE_DEBUG
69 for (auto &Arg : RCVec) {
70 Logger::logs("proteus")
71 << "{" << Arg.Value.Int64Val << ", " << Arg.Slot << " }\n";
72 }
73#endif
74
75 PROTEUS_DBG(Logger::logs("proteus") << "\t users" << "\n");
76 for (User *User : LambdaClass->users()) {
77 PROTEUS_DBG(Logger::logs("proteus") << *User << "\n");
78 if (isa<LoadInst>(User)) {
79 for (auto &Arg : RCVec) {
80 if (Arg.Slot == 0) {
81 Constant *C = getConstant(M.getContext(), User->getType(), Arg);
82 User->replaceAllUsesWith(C);
83 PROTEUS_DBG(Logger::logs("proteus")
84 << "[LambdaSpec] Replacing " << *User << " with " << *C
85 << "\n");
86 }
87 }
88 } else if (auto *GEP = dyn_cast<GetElementPtrInst>(User)) {
89 auto *GEPSlot = GEP->getOperand(User->getNumOperands() - 1);
90 ConstantInt *CI = dyn_cast<ConstantInt>(GEPSlot);
91 int Slot = CI->getZExtValue();
92 for (auto &Arg : RCVec) {
93 if (Arg.Slot == Slot) {
94 for (auto *GEPUser : GEP->users()) {
95 auto *LI = dyn_cast<LoadInst>(GEPUser);
96 if (!LI)
97 PROTEUS_FATAL_ERROR("Expected load instruction");
98 Type *LoadType = LI->getType();
99 Constant *C = getConstant(M.getContext(), LoadType, Arg);
100 LI->replaceAllUsesWith(C);
101 PROTEUS_DBG(Logger::logs("proteus")
102 << "[LambdaSpec] Replacing " << *User << " with "
103 << *C << "\n");
104 }
105 }
106 }
107 }
108 }
109 }
110};
111
112} // namespace proteus
113
114#endif
#define PROTEUS_DBG(x)
Definition Debug.h:7
#define PROTEUS_FATAL_ERROR(x)
Definition Error.h:4
static llvm::raw_ostream & logs(const std::string &Name)
Definition Logger.hpp:18
Definition TransformLambdaSpecialization.hpp:57
static void transform(Module &M, Function &F, const SmallVector< RuntimeConstant > &RCVec)
Definition TransformLambdaSpecialization.hpp:59
Definition JitEngine.cpp:20
Constant * getConstant(LLVMContext &Ctx, Type *ArgType, const RuntimeConstant &RC)
Definition TransformLambdaSpecialization.hpp:28
Definition CompilerInterfaceTypes.h:30
RuntimeConstantType Value
Definition CompilerInterfaceTypes.h:43