Proteus
Programmable JIT compilation and optimization for C/C++ using LLVM
Loading...
Searching...
No Matches
TransformSharedArray.hpp
Go to the documentation of this file.
1//===-- TransformSharedArray.hpp -- Shared array with specialized size--===//
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_SHARED_ARRAY_HPP
12#define PROTEUS_TRANSFORM_SHARED_ARRAY_HPP
13
14#include <llvm/Analysis/ConstantFolding.h>
15#include <llvm/Demangle/Demangle.h>
16#include <llvm/IR/IRBuilder.h>
17#include <llvm/IR/Verifier.h>
18#include <llvm/Support/Debug.h>
19
20#include "proteus/Debug.h"
21#include "proteus/Logger.hpp"
22#include "proteus/Utils.h"
23
24namespace proteus {
25
26using namespace llvm;
27
29public:
30 static void transform(Module &M) {
31 for (auto &Func : M.functions()) {
32 std::string DemangledName = llvm::demangle(Func.getName().str());
34 if (StrRef.contains("proteus::shared_array")) {
35 // Use a while loop to delete while iterating.
36 while (!Func.user_empty()) {
37 User *Usr = *Func.user_begin();
38 if (!isa<CallBase>(Usr))
39 PROTEUS_FATAL_ERROR("Expected call user");
40
42 assert(CB->arg_size() == 2 && "Expected 2 arguments: N and sizeof");
43 int64_t N;
45 if (!getConstantValue(CB->getArgOperand(0), N, M.getDataLayout()))
46 PROTEUS_FATAL_ERROR("Expected constant N argument");
47 if (!getConstantValue(CB->getArgOperand(1), Sizeof,
48 M.getDataLayout()))
49 PROTEUS_FATAL_ERROR("Expected constant Sizeof argument");
50
52 ArrayType::get(Type::getInt8Ty(M.getContext()), N * Sizeof);
53 constexpr unsigned SharedMemAddrSpace = 3;
55 M, AType, false, GlobalValue::InternalLinkage,
56 UndefValue::get(AType), ".proteus.shared", nullptr,
57 llvm::GlobalValue::NotThreadLocal, SharedMemAddrSpace, false);
58 // Using 16-byte alignment based on AOT code generation.
59 // TODO: Create or find an API to query the proper ABI alignment.
60 SharedMemGV->setAlignment(Align{16});
61
66 OS << "[SharedArray] " << "Replace CB " << DemangledName << " with "
67 << *SharedMemGV << "\n";
68
69 return S;
70 };
71
72 PROTEUS_DBG(Logger::logs("proteus")
74 if (Config::get().ProteusTraceOutput >= 1)
76
77 CB->replaceAllUsesWith(ConstantExpr::getAddrSpaceCast(
78 SharedMemGV, CB->getFunctionType()->getReturnType()));
79 CB->eraseFromParent();
80 }
81
82 if (Config::get().ProteusDebugOutput) {
83 if (verifyModule(M, &errs()))
85 "Broken module found, JIT compilation aborted!");
86 }
87 }
88 }
89 }
90
91private:
92 static bool getConstantValue(Value *V, int64_t &Result,
93 const DataLayout &DL) {
94 // Directly access the value of a constant.
96 Result = CI->getSExtValue();
97 return true;
98 }
99
100 // Fold an instruction.
102 if (Value *FoldedV = ConstantFoldInstruction(I, DL, nullptr)) {
104 Result = CI->getSExtValue();
105 return true;
106 }
107 }
108 }
109
110 return false;
111 }
112};
113
114} // namespace proteus
115
116#endif
#define PROTEUS_DBG(x)
Definition Debug.h:9
#define PROTEUS_FATAL_ERROR(x)
Definition Error.h:7
static Config & get()
Definition Config.hpp:298
StringRef getName() const
Definition Func.hpp:231
Definition Func.hpp:252
static void trace(llvm::StringRef Msg)
Definition Logger.hpp:30
static llvm::raw_ostream & logs(const std::string &Name)
Definition Logger.hpp:19
Definition TransformSharedArray.hpp:28
static void transform(Module &M)
Definition TransformSharedArray.hpp:30
Definition Helpers.h:138
Definition StorageCache.cpp:24
T getRuntimeConstantValue(void *Arg)
Definition CompilerInterfaceRuntimeConstantInfo.h:114