blob: 8f4a255040539168e296699163efd573522cc9bd [file] [log] [blame]
Zonr Changc383a502010-10-12 01:52:08 +08001/*
Stephen Hines5e3b6772012-03-21 08:02:10 -07002 * Copyright 2010-2012, The Android Open Source Project
Zonr Changc383a502010-10-12 01:52:08 +08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
zonr6315f762010-10-05 15:35:14 +080017#include "slang_backend.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070018
Stephen Hinese639eb52010-11-08 19:27:20 -080019#include <string>
20#include <vector>
21
Stephen Hines5e6d0d52011-11-22 19:42:41 -080022#include "bcinfo/BitcodeWrapper.h"
23
Stephen Hinese639eb52010-11-08 19:27:20 -080024#include "clang/AST/ASTContext.h"
25#include "clang/AST/Decl.h"
26#include "clang/AST/DeclGroup.h"
27
28#include "clang/Basic/Diagnostic.h"
29#include "clang/Basic/TargetInfo.h"
30#include "clang/Basic/TargetOptions.h"
31
32#include "clang/CodeGen/ModuleBuilder.h"
33
34#include "clang/Frontend/CodeGenOptions.h"
35#include "clang/Frontend/FrontendDiagnostic.h"
36
Jean-Luc Brouilletc10bc752015-05-04 23:02:25 -070037#include "llvm/ADT/Twine.h"
38#include "llvm/ADT/StringExtras.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080039
40#include "llvm/Bitcode/ReaderWriter.h"
41
42#include "llvm/CodeGen/RegAllocRegistry.h"
43#include "llvm/CodeGen/SchedulerRegistry.h"
44
Jean-Luc Brouilletc10bc752015-05-04 23:02:25 -070045#include "llvm/IR/Constant.h"
46#include "llvm/IR/Constants.h"
47#include "llvm/IR/DataLayout.h"
48#include "llvm/IR/DebugLoc.h"
49#include "llvm/IR/DerivedTypes.h"
50#include "llvm/IR/Function.h"
51#include "llvm/IR/IRBuilder.h"
52#include "llvm/IR/IRPrintingPasses.h"
Stephen Hines23c43582013-01-09 20:02:04 -080053#include "llvm/IR/LLVMContext.h"
Stephen Hines23c43582013-01-09 20:02:04 -080054#include "llvm/IR/Metadata.h"
Jean-Luc Brouilletc10bc752015-05-04 23:02:25 -070055#include "llvm/IR/Module.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070056
Logan Chien9207a2e2011-10-21 15:39:28 +080057#include "llvm/Transforms/IPO/PassManagerBuilder.h"
Shih-wei Liaofcc654a2011-06-22 04:47:33 -070058
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070059#include "llvm/Target/TargetMachine.h"
60#include "llvm/Target/TargetOptions.h"
Logan Chien9207a2e2011-10-21 15:39:28 +080061#include "llvm/Support/TargetRegistry.h"
Shih-wei Liao77703262011-07-02 11:30:32 -070062
63#include "llvm/MC/SubtargetFeature.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070064
Stephen Hines6e6578a2011-02-07 18:05:48 -080065#include "slang_assert.h"
Jean-Luc Brouilletc10bc752015-05-04 23:02:25 -070066#include "slang.h"
67#include "slang_rs_context.h"
68#include "slang_rs_export_foreach.h"
69#include "slang_rs_export_func.h"
70#include "slang_rs_export_type.h"
71#include "slang_rs_export_var.h"
72#include "slang_rs_metadata.h"
73
Stephen Hines552d8722013-12-18 12:21:50 -080074#include "strip_unknown_attributes.h"
Stephen Hines4cc499d2011-08-24 19:06:17 -070075#include "BitWriter_2_9/ReaderWriter_2_9.h"
Stephen Hines9b044ec2011-11-23 16:30:16 -080076#include "BitWriter_2_9_func/ReaderWriter_2_9_func.h"
Stephen Hinesd711dec2013-01-08 16:23:30 -080077#include "BitWriter_3_2/ReaderWriter_3_2.h"
zonr6315f762010-10-05 15:35:14 +080078
Stephen Hinese639eb52010-11-08 19:27:20 -080079namespace slang {
Shih-wei Liao462aefd2010-06-04 15:32:04 -070080
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080081void Backend::CreateFunctionPasses() {
82 if (!mPerFunctionPasses) {
Stephen Hinesc7069072015-03-18 14:53:14 -070083 mPerFunctionPasses = new llvm::legacy::FunctionPassManager(mpModule);
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080084
Shih-wei Liaofcc654a2011-06-22 04:47:33 -070085 llvm::PassManagerBuilder PMBuilder;
86 PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
87 PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080088 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080089}
90
91void Backend::CreateModulePasses() {
92 if (!mPerModulePasses) {
Stephen Hinesc7069072015-03-18 14:53:14 -070093 mPerModulePasses = new llvm::legacy::PassManager();
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080094
Shih-wei Liaofcc654a2011-06-22 04:47:33 -070095 llvm::PassManagerBuilder PMBuilder;
96 PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
97 PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
Shih-wei Liaofcc654a2011-06-22 04:47:33 -070098 if (mCodeGenOpts.UnitAtATime) {
99 PMBuilder.DisableUnitAtATime = 0;
100 } else {
101 PMBuilder.DisableUnitAtATime = 1;
102 }
103
104 if (mCodeGenOpts.UnrollLoops) {
105 PMBuilder.DisableUnrollLoops = 0;
106 } else {
107 PMBuilder.DisableUnrollLoops = 1;
108 }
109
Shih-wei Liaofcc654a2011-06-22 04:47:33 -0700110 PMBuilder.populateModulePassManager(*mPerModulePasses);
Stephen Hines552d8722013-12-18 12:21:50 -0800111 // Add a pass to strip off unknown/unsupported attributes.
112 mPerModulePasses->add(createStripUnknownAttributesPass());
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800113 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800114}
115
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700116bool Backend::CreateCodeGenPasses() {
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800117 if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object))
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700118 return true;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700119
120 // Now we add passes for code emitting
121 if (mCodeGenPasses) {
122 return true;
123 } else {
Stephen Hinesc7069072015-03-18 14:53:14 -0700124 mCodeGenPasses = new llvm::legacy::FunctionPassManager(mpModule);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700125 }
126
127 // Create the TargetMachine for generating code.
128 std::string Triple = mpModule->getTargetTriple();
129
130 std::string Error;
131 const llvm::Target* TargetInfo =
132 llvm::TargetRegistry::lookupTarget(Triple, Error);
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700133 if (TargetInfo == nullptr) {
Logan Chien9207a2e2011-10-21 15:39:28 +0800134 mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700135 return false;
136 }
137
Logan Chienac4e1852011-12-16 13:37:10 +0800138 // Target Machine Options
139 llvm::TargetOptions Options;
140
141 Options.NoFramePointerElim = mCodeGenOpts.DisableFPElim;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700142
143 // Use hardware FPU.
144 //
145 // FIXME: Need to detect the CPU capability and decide whether to use softfp.
146 // To use softfp, change following 2 lines to
147 //
Logan Chienac4e1852011-12-16 13:37:10 +0800148 // Options.FloatABIType = llvm::FloatABI::Soft;
149 // Options.UseSoftFloat = true;
150 Options.FloatABIType = llvm::FloatABI::Hard;
151 Options.UseSoftFloat = false;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700152
153 // BCC needs all unknown symbols resolved at compilation time. So we don't
154 // need any relocation model.
Logan Chienab992e52011-07-20 22:06:52 +0800155 llvm::Reloc::Model RM = llvm::Reloc::Static;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700156
Zonr Chang41ebf532010-10-13 18:29:18 +0800157 // This is set for the linker (specify how large of the virtual addresses we
158 // can access for all unknown symbols.)
Logan Chien9207a2e2011-10-21 15:39:28 +0800159 llvm::CodeModel::Model CM;
Stephen Hines0b754582015-04-07 13:59:57 -0700160 if (mpModule->getDataLayout().getPointerSize() == 4) {
Logan Chien9207a2e2011-10-21 15:39:28 +0800161 CM = llvm::CodeModel::Small;
162 } else {
Zonr Chang41ebf532010-10-13 18:29:18 +0800163 // The target may have pointer size greater than 32 (e.g. x86_64
164 // architecture) may need large data address model
Logan Chien9207a2e2011-10-21 15:39:28 +0800165 CM = llvm::CodeModel::Medium;
166 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700167
168 // Setup feature string
169 std::string FeaturesStr;
170 if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
171 llvm::SubtargetFeatures Features;
172
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700173 for (std::vector<std::string>::const_iterator
174 I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
175 I != E;
176 I++)
177 Features.AddFeature(*I);
178
179 FeaturesStr = Features.getString();
180 }
Logan Chien9207a2e2011-10-21 15:39:28 +0800181
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700182 llvm::TargetMachine *TM =
Logan Chien9207a2e2011-10-21 15:39:28 +0800183 TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
Logan Chienac4e1852011-12-16 13:37:10 +0800184 Options, RM, CM);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700185
186 // Register scheduler
187 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
188
189 // Register allocation policy:
190 // createFastRegisterAllocator: fast but bad quality
Logan Chien2c6bad52011-11-15 15:57:33 +0800191 // createGreedyRegisterAllocator: not so fast but good quality
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700192 llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
193 llvm::createFastRegisterAllocator :
Logan Chien2c6bad52011-11-15 15:57:33 +0800194 llvm::createGreedyRegisterAllocator);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700195
196 llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
Shih-wei Liao77703262011-07-02 11:30:32 -0700197 if (mCodeGenOpts.OptimizationLevel == 0) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700198 OptLevel = llvm::CodeGenOpt::None;
Shih-wei Liao77703262011-07-02 11:30:32 -0700199 } else if (mCodeGenOpts.OptimizationLevel == 3) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700200 OptLevel = llvm::CodeGenOpt::Aggressive;
Shih-wei Liao77703262011-07-02 11:30:32 -0700201 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700202
203 llvm::TargetMachine::CodeGenFileType CGFT =
zonr6315f762010-10-05 15:35:14 +0800204 llvm::TargetMachine::CGFT_AssemblyFile;
Shih-wei Liao77703262011-07-02 11:30:32 -0700205 if (mOT == Slang::OT_Object) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700206 CGFT = llvm::TargetMachine::CGFT_ObjectFile;
Shih-wei Liao77703262011-07-02 11:30:32 -0700207 }
Pirama Arumuga Nainar2444eaa2015-05-06 11:17:16 -0700208 if (TM->addPassesToEmitFile(*mCodeGenPasses, mBufferOutStream,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700209 CGFT, OptLevel)) {
Logan Chien9207a2e2011-10-21 15:39:28 +0800210 mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700211 return false;
212 }
213
214 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700215}
216
Jean-Luc Brouilletc10bc752015-05-04 23:02:25 -0700217Backend::Backend(RSContext *Context, clang::DiagnosticsEngine *DiagEngine,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700218 const clang::CodeGenOptions &CodeGenOpts,
Jean-Luc Brouilletc10bc752015-05-04 23:02:25 -0700219 const clang::TargetOptions &TargetOpts, PragmaList *Pragmas,
220 llvm::raw_ostream *OS, Slang::OutputType OT,
221 clang::SourceManager &SourceMgr, bool AllowRSPrefix,
222 bool IsFilterscript)
223 : ASTConsumer(), mTargetOpts(TargetOpts), mpModule(nullptr), mpOS(OS),
224 mOT(OT), mGen(nullptr), mPerFunctionPasses(nullptr),
Pirama Arumuga Nainar2444eaa2015-05-06 11:17:16 -0700225 mPerModulePasses(nullptr), mCodeGenPasses(nullptr),
226 mBufferOutStream(*mpOS), mContext(Context),
Jean-Luc Brouilletc10bc752015-05-04 23:02:25 -0700227 mSourceMgr(SourceMgr), mAllowRSPrefix(AllowRSPrefix),
228 mIsFilterscript(IsFilterscript), mExportVarMetadata(nullptr),
229 mExportFuncMetadata(nullptr), mExportForEachNameMetadata(nullptr),
230 mExportForEachSignatureMetadata(nullptr), mExportTypeMetadata(nullptr),
231 mRSObjectSlotsMetadata(nullptr), mRefCount(mContext->getASTContext()),
232 mASTChecker(Context, Context->getTargetAPI(), IsFilterscript),
233 mLLVMContext(llvm::getGlobalContext()), mDiagEngine(*DiagEngine),
234 mCodeGenOpts(CodeGenOpts), mPragmas(Pragmas) {
Stephen Hinesc7069072015-03-18 14:53:14 -0700235 mGen = CreateLLVMCodeGen(mDiagEngine, "", mCodeGenOpts, mLLVMContext);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700236}
237
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700238void Backend::Initialize(clang::ASTContext &Ctx) {
239 mGen->Initialize(Ctx);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700240
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700241 mpModule = mGen->GetModule();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700242}
243
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800244// Encase the Bitcode in a wrapper containing RS version information.
245void Backend::WrapBitcode(llvm::raw_string_ostream &Bitcode) {
Stephen Hines5e3b6772012-03-21 08:02:10 -0700246 bcinfo::AndroidBitcodeWrapper wrapper;
247 size_t actualWrapperLen = bcinfo::writeAndroidBitcodeWrapper(
248 &wrapper, Bitcode.str().length(), getTargetAPI(),
249 SlangVersion::CURRENT, mCodeGenOpts.OptimizationLevel);
250
251 slangAssert(actualWrapperLen > 0);
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800252
253 // Write out the bitcode wrapper.
Pirama Arumuga Nainar2444eaa2015-05-06 11:17:16 -0700254 mBufferOutStream.write(reinterpret_cast<char*>(&wrapper), actualWrapperLen);
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800255
256 // Write out the actual encoded bitcode.
Pirama Arumuga Nainar2444eaa2015-05-06 11:17:16 -0700257 mBufferOutStream << Bitcode.str();
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800258}
259
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700260void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
Zonr Chang68fc02c2010-10-13 19:09:19 +0800261 HandleTranslationUnitPre(Ctx);
262
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700263 mGen->HandleTranslationUnit(Ctx);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700264
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700265 // Here, we complete a translation unit (whole translation unit is now in LLVM
266 // IR). Now, interact with LLVM backend to generate actual machine code (asm
267 // or machine code, whatever.)
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700268
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700269 // Silently ignore if we weren't initialized for some reason.
Zonr Chang41ebf532010-10-13 18:29:18 +0800270 if (!mpModule)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700271 return;
272
273 llvm::Module *M = mGen->ReleaseModule();
274 if (!M) {
275 // The module has been released by IR gen on failures, do not double free.
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700276 mpModule = nullptr;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700277 return;
278 }
279
Stephen Hines6e6578a2011-02-07 18:05:48 -0800280 slangAssert(mpModule == M &&
281 "Unexpected module change during LLVM IR generation");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700282
283 // Insert #pragma information into metadata section of module
Stephen Hines3fd0a942011-01-18 12:27:39 -0800284 if (!mPragmas->empty()) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700285 llvm::NamedMDNode *PragmaMetadata =
286 mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
Stephen Hines3fd0a942011-01-18 12:27:39 -0800287 for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700288 I != E;
289 I++) {
Stephen Hinesc7069072015-03-18 14:53:14 -0700290 llvm::SmallVector<llvm::Metadata*, 2> Pragma;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700291 // Name goes first
292 Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
293 // And then value
294 Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
Shih-wei Liao83f0c622011-06-21 05:34:53 -0700295
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700296 // Create MDNode and insert into PragmaMetadata
297 PragmaMetadata->addOperand(
Stephen Hines18c88292011-07-14 22:46:15 -0700298 llvm::MDNode::get(mLLVMContext, Pragma));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700299 }
300 }
301
Zonr Chang68fc02c2010-10-13 19:09:19 +0800302 HandleTranslationUnitPost(mpModule);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700303
304 // Create passes for optimization and code emission
305
306 // Create and run per-function passes
307 CreateFunctionPasses();
308 if (mPerFunctionPasses) {
309 mPerFunctionPasses->doInitialization();
310
311 for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
312 I != E;
313 I++)
314 if (!I->isDeclaration())
315 mPerFunctionPasses->run(*I);
316
317 mPerFunctionPasses->doFinalization();
318 }
319
320 // Create and run module passes
321 CreateModulePasses();
322 if (mPerModulePasses)
323 mPerModulePasses->run(*mpModule);
324
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800325 switch (mOT) {
326 case Slang::OT_Assembly:
327 case Slang::OT_Object: {
zonr6315f762010-10-05 15:35:14 +0800328 if (!CreateCodeGenPasses())
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700329 return;
330
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700331 mCodeGenPasses->doInitialization();
332
333 for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
334 I != E;
335 I++)
zonr6315f762010-10-05 15:35:14 +0800336 if (!I->isDeclaration())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700337 mCodeGenPasses->run(*I);
338
339 mCodeGenPasses->doFinalization();
340 break;
341 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800342 case Slang::OT_LLVMAssembly: {
Stephen Hinesc7069072015-03-18 14:53:14 -0700343 llvm::legacy::PassManager *LLEmitPM = new llvm::legacy::PassManager();
Pirama Arumuga Nainar2444eaa2015-05-06 11:17:16 -0700344 LLEmitPM->add(llvm::createPrintModulePass(mBufferOutStream));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700345 LLEmitPM->run(*mpModule);
346 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700347 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800348 case Slang::OT_Bitcode: {
Stephen Hinesc7069072015-03-18 14:53:14 -0700349 llvm::legacy::PassManager *BCEmitPM = new llvm::legacy::PassManager();
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800350 std::string BCStr;
351 llvm::raw_string_ostream Bitcode(BCStr);
Chris Wailesc9454af2014-06-13 17:25:40 -0700352 unsigned int TargetAPI = getTargetAPI();
Stephen Hines9b044ec2011-11-23 16:30:16 -0800353 switch (TargetAPI) {
354 case SLANG_HC_TARGET_API:
355 case SLANG_HC_MR1_TARGET_API:
356 case SLANG_HC_MR2_TARGET_API: {
357 // Pre-ICS targets must use the LLVM 2.9 BitcodeWriter
358 BCEmitPM->add(llvm_2_9::createBitcodeWriterPass(Bitcode));
359 break;
360 }
361 case SLANG_ICS_TARGET_API:
362 case SLANG_ICS_MR1_TARGET_API: {
363 // ICS targets must use the LLVM 2.9_func BitcodeWriter
364 BCEmitPM->add(llvm_2_9_func::createBitcodeWriterPass(Bitcode));
365 break;
366 }
367 default: {
Chris Wailes9e3aa072014-06-16 18:52:02 -0700368 if (TargetAPI != SLANG_DEVELOPMENT_TARGET_API &&
369 (TargetAPI < SLANG_MINIMUM_TARGET_API ||
370 TargetAPI > SLANG_MAXIMUM_TARGET_API)) {
Stephen Hines9b044ec2011-11-23 16:30:16 -0800371 slangAssert(false && "Invalid target API value");
372 }
Stephen Hinesd711dec2013-01-08 16:23:30 -0800373 // Switch to the 3.2 BitcodeWriter by default, and don't use
374 // LLVM's included BitcodeWriter at all (for now).
375 BCEmitPM->add(llvm_3_2::createBitcodeWriterPass(Bitcode));
376 //BCEmitPM->add(llvm::createBitcodeWriterPass(Bitcode));
Stephen Hines9b044ec2011-11-23 16:30:16 -0800377 break;
378 }
Stephen Hines4cc499d2011-08-24 19:06:17 -0700379 }
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800380
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700381 BCEmitPM->run(*mpModule);
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800382 WrapBitcode(Bitcode);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700383 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700384 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800385 case Slang::OT_Nothing: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700386 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700387 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700388 default: {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800389 slangAssert(false && "Unknown output type");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700390 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700391 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700392
Pirama Arumuga Nainar2444eaa2015-05-06 11:17:16 -0700393 mBufferOutStream.flush();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700394}
395
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700396void Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
397 mGen->HandleTagDeclDefinition(D);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700398}
399
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700400void Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
401 mGen->CompleteTentativeDefinition(D);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700402}
403
404Backend::~Backend() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700405 delete mpModule;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700406 delete mGen;
407 delete mPerFunctionPasses;
408 delete mPerModulePasses;
409 delete mCodeGenPasses;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700410}
Stephen Hinese639eb52010-11-08 19:27:20 -0800411
Jean-Luc Brouilletc10bc752015-05-04 23:02:25 -0700412// 1) Add zero initialization of local RS object types
413void Backend::AnnotateFunction(clang::FunctionDecl *FD) {
414 if (FD &&
415 FD->hasBody() &&
416 !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
417 mRefCount.Init();
418 mRefCount.Visit(FD->getBody());
419 }
420}
421
422bool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
423 // Disallow user-defined functions with prefix "rs"
424 if (!mAllowRSPrefix) {
425 // Iterate all function declarations in the program.
426 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
427 I != E; I++) {
428 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
429 if (FD == nullptr)
430 continue;
431 if (!FD->getName().startswith("rs")) // Check prefix
432 continue;
433 if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
434 mContext->ReportError(FD->getLocation(),
435 "invalid function name prefix, "
436 "\"rs\" is reserved: '%0'")
437 << FD->getName();
438 }
439 }
440
441 // Process any non-static function declarations
442 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
443 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
444 if (FD && FD->isGlobal()) {
445 // Check that we don't have any array parameters being misintrepeted as
446 // kernel pointers due to the C type system's array to pointer decay.
447 size_t numParams = FD->getNumParams();
448 for (size_t i = 0; i < numParams; i++) {
449 const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
450 clang::QualType QT = PVD->getOriginalType();
451 if (QT->isArrayType()) {
452 mContext->ReportError(
453 PVD->getTypeSpecStartLoc(),
454 "exported function parameters may not have array type: %0")
455 << QT;
456 }
457 }
458 AnnotateFunction(FD);
459 }
460 }
461 return mGen->HandleTopLevelDecl(D);
462}
463
464void Backend::HandleTranslationUnitPre(clang::ASTContext &C) {
465 clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
466
467 // If we have an invalid RS/FS AST, don't check further.
468 if (!mASTChecker.Validate()) {
469 return;
470 }
471
472 if (mIsFilterscript) {
473 mContext->addPragma("rs_fp_relaxed", "");
474 }
475
476 int version = mContext->getVersion();
477 if (version == 0) {
478 // Not setting a version is an error
479 mDiagEngine.Report(
480 mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
481 mDiagEngine.getCustomDiagID(
482 clang::DiagnosticsEngine::Error,
483 "missing pragma for version in source file"));
484 } else {
485 slangAssert(version == 1);
486 }
487
488 if (mContext->getReflectJavaPackageName().empty()) {
489 mDiagEngine.Report(
490 mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
491 mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
492 "missing \"#pragma rs "
493 "java_package_name(com.foo.bar)\" "
494 "in source file"));
495 return;
496 }
497
498 // Create a static global destructor if necessary (to handle RS object
499 // runtime cleanup).
500 clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
501 if (FD) {
502 HandleTopLevelDecl(clang::DeclGroupRef(FD));
503 }
504
505 // Process any static function declarations
506 for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
507 E = TUDecl->decls_end(); I != E; I++) {
508 if ((I->getKind() >= clang::Decl::firstFunction) &&
509 (I->getKind() <= clang::Decl::lastFunction)) {
510 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
511 if (FD && !FD->isGlobal()) {
512 AnnotateFunction(FD);
513 }
514 }
515 }
516}
517
518///////////////////////////////////////////////////////////////////////////////
519void Backend::dumpExportVarInfo(llvm::Module *M) {
520 int slotCount = 0;
521 if (mExportVarMetadata == nullptr)
522 mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
523
524 llvm::SmallVector<llvm::Metadata *, 2> ExportVarInfo;
525
526 // We emit slot information (#rs_object_slots) for any reference counted
527 // RS type or pointer (which can also be bound).
528
529 for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
530 E = mContext->export_vars_end();
531 I != E;
532 I++) {
533 const RSExportVar *EV = *I;
534 const RSExportType *ET = EV->getType();
535 bool countsAsRSObject = false;
536
537 // Variable name
538 ExportVarInfo.push_back(
539 llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
540
541 // Type name
542 switch (ET->getClass()) {
543 case RSExportType::ExportClassPrimitive: {
544 const RSExportPrimitiveType *PT =
545 static_cast<const RSExportPrimitiveType*>(ET);
546 ExportVarInfo.push_back(
547 llvm::MDString::get(
548 mLLVMContext, llvm::utostr_32(PT->getType())));
549 if (PT->isRSObjectType()) {
550 countsAsRSObject = true;
551 }
552 break;
553 }
554 case RSExportType::ExportClassPointer: {
555 ExportVarInfo.push_back(
556 llvm::MDString::get(
557 mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
558 ->getPointeeType()->getName()).c_str()));
559 break;
560 }
561 case RSExportType::ExportClassMatrix: {
562 ExportVarInfo.push_back(
563 llvm::MDString::get(
564 mLLVMContext, llvm::utostr_32(
565 /* TODO Strange value. This pushes just a number, quite
566 * different than the other cases. What is this used for?
567 * These are the metadata values that some partner drivers
568 * want to reference (for TBAA, etc.). We may want to look
569 * at whether these provide any reasonable value (or have
570 * distinct enough values to actually depend on).
571 */
572 DataTypeRSMatrix2x2 +
573 static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
574 break;
575 }
576 case RSExportType::ExportClassVector:
577 case RSExportType::ExportClassConstantArray:
578 case RSExportType::ExportClassRecord: {
579 ExportVarInfo.push_back(
580 llvm::MDString::get(mLLVMContext,
581 EV->getType()->getName().c_str()));
582 break;
583 }
584 }
585
586 mExportVarMetadata->addOperand(
587 llvm::MDNode::get(mLLVMContext, ExportVarInfo));
588 ExportVarInfo.clear();
589
590 if (mRSObjectSlotsMetadata == nullptr) {
591 mRSObjectSlotsMetadata =
592 M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
593 }
594
595 if (countsAsRSObject) {
596 mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
597 llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
598 }
599
600 slotCount++;
601 }
602}
603
604void Backend::dumpExportFunctionInfo(llvm::Module *M) {
605 if (mExportFuncMetadata == nullptr)
606 mExportFuncMetadata =
607 M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
608
609 llvm::SmallVector<llvm::Metadata *, 1> ExportFuncInfo;
610
611 for (RSContext::const_export_func_iterator
612 I = mContext->export_funcs_begin(),
613 E = mContext->export_funcs_end();
614 I != E;
615 I++) {
616 const RSExportFunc *EF = *I;
617
618 // Function name
619 if (!EF->hasParam()) {
620 ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
621 EF->getName().c_str()));
622 } else {
623 llvm::Function *F = M->getFunction(EF->getName());
624 llvm::Function *HelperFunction;
625 const std::string HelperFunctionName(".helper_" + EF->getName());
626
627 slangAssert(F && "Function marked as exported disappeared in Bitcode");
628
629 // Create helper function
630 {
631 llvm::StructType *HelperFunctionParameterTy = nullptr;
632 std::vector<bool> isStructInput;
633
634 if (!F->getArgumentList().empty()) {
635 std::vector<llvm::Type*> HelperFunctionParameterTys;
636 for (llvm::Function::arg_iterator AI = F->arg_begin(),
637 AE = F->arg_end(); AI != AE; AI++) {
638 if (AI->getType()->isPointerTy() && AI->getType()->getPointerElementType()->isStructTy()) {
639 HelperFunctionParameterTys.push_back(AI->getType()->getPointerElementType());
640 isStructInput.push_back(true);
641 } else {
642 HelperFunctionParameterTys.push_back(AI->getType());
643 isStructInput.push_back(false);
644 }
645 }
646 HelperFunctionParameterTy =
647 llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
648 }
649
650 if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
651 fprintf(stderr, "Failed to export function %s: parameter type "
652 "mismatch during creation of helper function.\n",
653 EF->getName().c_str());
654
655 const RSExportRecordType *Expected = EF->getParamPacketType();
656 if (Expected) {
657 fprintf(stderr, "Expected:\n");
658 Expected->getLLVMType()->dump();
659 }
660 if (HelperFunctionParameterTy) {
661 fprintf(stderr, "Got:\n");
662 HelperFunctionParameterTy->dump();
663 }
664 }
665
666 std::vector<llvm::Type*> Params;
667 if (HelperFunctionParameterTy) {
668 llvm::PointerType *HelperFunctionParameterTyP =
669 llvm::PointerType::getUnqual(HelperFunctionParameterTy);
670 Params.push_back(HelperFunctionParameterTyP);
671 }
672
673 llvm::FunctionType * HelperFunctionType =
674 llvm::FunctionType::get(F->getReturnType(),
675 Params,
676 /* IsVarArgs = */false);
677
678 HelperFunction =
679 llvm::Function::Create(HelperFunctionType,
680 llvm::GlobalValue::ExternalLinkage,
681 HelperFunctionName,
682 M);
683
684 HelperFunction->addFnAttr(llvm::Attribute::NoInline);
685 HelperFunction->setCallingConv(F->getCallingConv());
686
687 // Create helper function body
688 {
689 llvm::Argument *HelperFunctionParameter =
690 &(*HelperFunction->arg_begin());
691 llvm::BasicBlock *BB =
692 llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
693 llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
694 llvm::SmallVector<llvm::Value*, 6> Params;
695 llvm::Value *Idx[2];
696
697 Idx[0] =
698 llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
699
700 // getelementptr and load instruction for all elements in
701 // parameter .p
702 for (size_t i = 0; i < EF->getNumParameters(); i++) {
703 // getelementptr
704 Idx[1] = llvm::ConstantInt::get(
705 llvm::Type::getInt32Ty(mLLVMContext), i);
706
707 llvm::Value *Ptr = NULL;
708
709 Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
710
711 // Load is only required for non-struct ptrs
712 if (isStructInput[i]) {
713 Params.push_back(Ptr);
714 } else {
715 llvm::Value *V = IB->CreateLoad(Ptr);
716 Params.push_back(V);
717 }
718 }
719
720 // Call and pass the all elements as parameter to F
721 llvm::CallInst *CI = IB->CreateCall(F, Params);
722
723 CI->setCallingConv(F->getCallingConv());
724
725 if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
726 IB->CreateRetVoid();
727 else
728 IB->CreateRet(CI);
729
730 delete IB;
731 }
732 }
733
734 ExportFuncInfo.push_back(
735 llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
736 }
737
738 mExportFuncMetadata->addOperand(
739 llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
740 ExportFuncInfo.clear();
741 }
742}
743
744void Backend::dumpExportForEachInfo(llvm::Module *M) {
745 if (mExportForEachNameMetadata == nullptr) {
746 mExportForEachNameMetadata =
747 M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
748 }
749 if (mExportForEachSignatureMetadata == nullptr) {
750 mExportForEachSignatureMetadata =
751 M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
752 }
753
754 llvm::SmallVector<llvm::Metadata *, 1> ExportForEachName;
755 llvm::SmallVector<llvm::Metadata *, 1> ExportForEachInfo;
756
757 for (RSContext::const_export_foreach_iterator
758 I = mContext->export_foreach_begin(),
759 E = mContext->export_foreach_end();
760 I != E;
761 I++) {
762 const RSExportForEach *EFE = *I;
763
764 ExportForEachName.push_back(
765 llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
766
767 mExportForEachNameMetadata->addOperand(
768 llvm::MDNode::get(mLLVMContext, ExportForEachName));
769 ExportForEachName.clear();
770
771 ExportForEachInfo.push_back(
772 llvm::MDString::get(mLLVMContext,
773 llvm::utostr_32(EFE->getSignatureMetadata())));
774
775 mExportForEachSignatureMetadata->addOperand(
776 llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
777 ExportForEachInfo.clear();
778 }
779}
780
781void Backend::dumpExportTypeInfo(llvm::Module *M) {
782 llvm::SmallVector<llvm::Metadata *, 1> ExportTypeInfo;
783
784 for (RSContext::const_export_type_iterator
785 I = mContext->export_types_begin(),
786 E = mContext->export_types_end();
787 I != E;
788 I++) {
789 // First, dump type name list to export
790 const RSExportType *ET = I->getValue();
791
792 ExportTypeInfo.clear();
793 // Type name
794 ExportTypeInfo.push_back(
795 llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
796
797 if (ET->getClass() == RSExportType::ExportClassRecord) {
798 const RSExportRecordType *ERT =
799 static_cast<const RSExportRecordType*>(ET);
800
801 if (mExportTypeMetadata == nullptr)
802 mExportTypeMetadata =
803 M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
804
805 mExportTypeMetadata->addOperand(
806 llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
807
808 // Now, export struct field information to %[struct name]
809 std::string StructInfoMetadataName("%");
810 StructInfoMetadataName.append(ET->getName());
811 llvm::NamedMDNode *StructInfoMetadata =
812 M->getOrInsertNamedMetadata(StructInfoMetadataName);
813 llvm::SmallVector<llvm::Metadata *, 3> FieldInfo;
814
815 slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
816 "Metadata with same name was created before");
817 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
818 FE = ERT->fields_end();
819 FI != FE;
820 FI++) {
821 const RSExportRecordType::Field *F = *FI;
822
823 // 1. field name
824 FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
825 F->getName().c_str()));
826
827 // 2. field type name
828 FieldInfo.push_back(
829 llvm::MDString::get(mLLVMContext,
830 F->getType()->getName().c_str()));
831
832 StructInfoMetadata->addOperand(
833 llvm::MDNode::get(mLLVMContext, FieldInfo));
834 FieldInfo.clear();
835 }
836 } // ET->getClass() == RSExportType::ExportClassRecord
837 }
838}
839
840void Backend::HandleTranslationUnitPost(llvm::Module *M) {
841
842 if (!mContext->is64Bit()) {
843 M->setDataLayout("e-p:32:32-i64:64-v128:64:128-n32-S64");
844 }
845
846 if (!mContext->processExport()) {
847 return;
848 }
849
850 if (mContext->hasExportVar())
851 dumpExportVarInfo(M);
852
853 if (mContext->hasExportFunc())
854 dumpExportFunctionInfo(M);
855
856 if (mContext->hasExportForEach())
857 dumpExportForEachInfo(M);
858
859 if (mContext->hasExportType())
860 dumpExportTypeInfo(M);
861}
862
Stephen Hinese639eb52010-11-08 19:27:20 -0800863} // namespace slang