Proteus
Programmable JIT compilation and optimization for C/C++ using LLVM
Loading...
Searching...
No Matches
TransformArgumentSpecialization.hpp
Go to the documentation of this file.
1//===-- TransformArgumentSpecialization.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_ARGUMENT_SPECIALIZATION_HPP
12#define PROTEUS_TRANSFORM_ARGUMENT_SPECIALIZATION_HPP
13
14#include <llvm/IR/IRBuilder.h>
15#include <llvm/Support/Debug.h>
16
18#include "proteus/Debug.h"
19#include "proteus/Utils.h"
20
21namespace proteus {
22
23using namespace llvm;
24
26public:
27 static void transform(Module &M, Function &F,
28 ArrayRef<RuntimeConstant> RCArray) {
29 auto &Ctx = M.getContext();
30
31 // Replace argument uses with runtime constants.
32 for (const auto &RC : RCArray) {
33 int ArgNo = RC.Pos;
34 Value *Arg = F.getArg(ArgNo);
35 Type *ArgType = Arg->getType();
36 Constant *C = nullptr;
37
38 if (ArgType->isIntegerTy(1)) {
39 C = ConstantInt::get(ArgType, RC.Value.BoolVal);
40 } else if (ArgType->isIntegerTy(8)) {
41 C = ConstantInt::get(ArgType, RC.Value.Int8Val);
42 } else if (ArgType->isIntegerTy(32)) {
43 // Logger::logs("proteus") << "RC is Int32\n";
44 C = ConstantInt::get(ArgType, RC.Value.Int32Val);
45 } else if (ArgType->isIntegerTy(64)) {
46 // Logger::logs("proteus") << "RC is Int64\n";
47 C = ConstantInt::get(ArgType, RC.Value.Int64Val);
48 } else if (ArgType->isFloatTy()) {
49 // Logger::logs("proteus") << "RC is Float\n";
50 C = ConstantFP::get(ArgType, RC.Value.FloatVal);
51 } else if (ArgType->isDoubleTy()) {
52 // NOTE: long double on device should correspond to plain double.
53 // XXX: CUDA with a long double SILENTLY fails to create a working
54 // kernel in AOT compilation, with or without JIT.
56 C = ConstantFP::get(ArgType, RC.Value.LongDoubleVal);
57 else
58 C = ConstantFP::get(ArgType, RC.Value.DoubleVal);
59 } else if (ArgType->isX86_FP80Ty() || ArgType->isPPC_FP128Ty() ||
60 ArgType->isFP128Ty()) {
61 C = ConstantFP::get(ArgType, RC.Value.LongDoubleVal);
62 } else if (ArgType->isPointerTy()) {
63 auto *IntC = ConstantInt::get(Type::getInt64Ty(Ctx), RC.Value.Int64Val);
64 C = ConstantExpr::getIntToPtr(IntC, ArgType);
65 } else {
66 std::string TypeString;
67 raw_string_ostream TypeOstream(TypeString);
68 ArgType->print(TypeOstream);
69 PROTEUS_FATAL_ERROR("JIT Incompatible type in runtime constant: " +
70 TypeOstream.str());
71 }
72
73 auto TraceOut = [](Function &F, int ArgNo, Constant *C) {
74 SmallString<128> S;
75 raw_svector_ostream OS(S);
76 OS << "[ArgSpec] Replaced Function " << F.getName() << " ArgNo "
77 << ArgNo << " with value " << *C << "\n";
78
79 return S;
80 };
81
82 PROTEUS_DBG(Logger::logs("proteus") << TraceOut(F, ArgNo, C));
83 if (Config::get().ProteusTraceOutput)
84 Logger::trace(TraceOut(F, ArgNo, C));
85 Arg->replaceAllUsesWith(C);
86 }
87 }
88};
89
90} // namespace proteus
91
92#endif
#define PROTEUS_DBG(x)
Definition Debug.h:10
#define PROTEUS_FATAL_ERROR(x)
Definition Error.h:4
static Config & get()
Definition Config.hpp:112
static void trace(llvm::StringRef Msg)
Definition Logger.hpp:30
static llvm::raw_ostream & logs(const std::string &Name)
Definition Logger.hpp:19
Definition TransformArgumentSpecialization.hpp:25
static void transform(Module &M, Function &F, ArrayRef< RuntimeConstant > RCArray)
Definition TransformArgumentSpecialization.hpp:27
Definition Dispatcher.cpp:14
@ LONG_DOUBLE
Definition CompilerInterfaceTypes.h:26