OpenASIP 2.2
Loading...
Searching...
No Matches
LowerIntrinsics.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2023 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24
25/**
26 * @file LowerIntrinsics.cc
27 *
28 * Converts llvm intrinsics to libcalls.
29 *
30 * @author Veli-Pekka Jaaskelainen 2008 (vjaaskel-no.spam-cs.tut.fi)
31 * @author Mikael Lepistö 2009 (mikael.lepisto-no.spam-tut.fi)
32 * @author Joonas Multanen 2023 (joonas.multanen-no.spam-tuni.fi)
33 */
34
35#define DEBUG_TYPE "lowerintrinsics"
36
37#include <CompilerWarnings.hh>
38IGNORE_COMPILER_WARNING("-Wunused-parameter")
39
40#include <llvm/Transforms/Scalar.h>
41#include <llvm/Transforms/Utils/UnifyFunctionExitNodes.h>
42#include <tce_config.h>
43#include <llvm/IR/Module.h>
44#include <llvm/IR/Instructions.h>
45#include <llvm/IR/Constants.h>
46#include <llvm/IR/Intrinsics.h>
47#include <llvm/IR/DerivedTypes.h>
48#include <llvm/IR/LLVMContext.h>
49#include <llvm/Support/Compiler.h>
50#include <llvm/IR/Function.h>
51#include <llvm/Pass.h>
52#include <llvm/Passes/PassBuilder.h>
53#include <llvm/Passes/PassPlugin.h>
54#include <llvm/CodeGen/IntrinsicLowering.h>
55#include <tce_config.h>
56
58
59#include <llvm/IR/DataLayout.h>
60typedef llvm::DataLayout TargetData;
61
62using namespace llvm;
63
64#include <iostream>
65#include <set>
66
67
68class LowerIntrinsics : public PassInfoMixin<LowerIntrinsics> {
69public:
70 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
71
72 // to suppress Clang warnings
73 //using llvm::FunctionPass::doInitialization;
74 //using llvm::FunctionPass::doFinalization;
75
76 bool runOnBasicBlock(BasicBlock &BB);
77
78private:
79 bool doInitialization(Module &M);
80 bool doFinalization (Module &M);
81 /// List of intrinsics to replace.
82 std::set<unsigned> replace_;
83 IntrinsicLowering* iLowering_;
85};
86
87PreservedAnalyses LowerIntrinsics::run(Function &F,
88 FunctionAnalysisManager &AM) {
89 //errs() << F.getName() << "\n";
90 Module *parentModule = F.getParent();
91 doInitialization(*parentModule);
92 for (BasicBlock &BB : F) {
94 }
95 doFinalization(*parentModule);
96 return PreservedAnalyses::all();
97}
98
99
100bool
102
103 // Initialize list of intrinsics to lower.
104 replace_.insert(Intrinsic::get_rounding);
105 replace_.insert(Intrinsic::ceil);
106 replace_.insert(Intrinsic::floor);
107 replace_.insert(Intrinsic::round);
108 replace_.insert(Intrinsic::exp2);
109 replace_.insert(Intrinsic::memcpy);
110 replace_.insert(Intrinsic::memset);
111 replace_.insert(Intrinsic::memmove);
112
113 assert(iLowering_ == NULL && td_ == NULL);
114 td_ = new TargetData(&M);
115 iLowering_ = new IntrinsicLowering(*td_);
116 return true;
117}
118
119bool
121 if (iLowering_ != NULL) {
122 delete iLowering_;
123 iLowering_ = NULL;
124 }
125 if (td_ != NULL) {
126 delete td_;
127 td_ = NULL;
128 }
129 return true;
130}
131
132
133bool
135 bool changed = true;
136 while (changed) {
137 changed = false;
138 for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) {
139 CallInst* ci = dyn_cast<CallInst>(&(*I));
140 if (ci != NULL && ci->arg_size() != 0) {
141 Function* callee = ci->getCalledFunction();
142 if (callee != NULL && callee->isIntrinsic() &&
143 replace_.find(callee->getIntrinsicID()) != replace_.end()) {
144 if (callee->getIntrinsicID() == Intrinsic::get_rounding) {
145 // Replace GET_ROUNDING intrinsic with the actual
146 // constant value to avoid stupid "if (1 == 0)"
147 // code even with full optimizations.
148 I->replaceAllUsesWith(
149 ConstantInt::get(
150 Type::getInt32Ty(BB.getContext()), 0, true));
151 I->eraseFromParent();
152 changed = true;
153 break;
154 } else {
155 iLowering_->LowerIntrinsicCall(ci);
156 changed = true;
157 break;
158 }
159 }
160 }
161 }
162 }
163 return true;
164}
165
166
167/* New PM Registration */
168llvm::PassPluginLibraryInfo getLowerIntrinsicsPluginInfo() {
169 return {LLVM_PLUGIN_API_VERSION, "LowerIntrinsics", LLVM_VERSION_STRING,
170 [](PassBuilder &PB) {
171 PB.registerVectorizerStartEPCallback(
172 [](llvm::FunctionPassManager &PM, OptimizationLevel Level) {
173 PM.addPass(LowerIntrinsics());
174 });
175 PB.registerPipelineParsingCallback(
176 [](StringRef Name, llvm::FunctionPassManager &PM,
177 ArrayRef<llvm::PassBuilder::PipelineElement>) {
178 if (Name == "lowerintrinsic") {
179 PM.addPass(LowerIntrinsics());
180 return true;
181 }
182 return false;
183 });
184 }};
185}
186
187#ifndef LLVM_LOWERINTRINSICS_LINK_INTO_TOOLS
188extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
192#endif
#define assert(condition)
#define IGNORE_COMPILER_WARNING(X)
#define POP_COMPILER_DIAGS
llvm::DataLayout TargetData
POP_COMPILER_DIAGS typedef llvm::DataLayout TargetData
llvm::PassPluginLibraryInfo getLowerIntrinsicsPluginInfo()
LLVM_ATTRIBUTE_WEAK::llvm::PassPluginLibraryInfo llvmGetPassPluginInfo()
bool doInitialization(Module &M)
bool doFinalization(Module &M)
bool runOnBasicBlock(BasicBlock &BB)
IntrinsicLowering * iLowering_
std::set< unsigned > replace_
List of intrinsics to replace.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)