slang_backend.cpp revision 352e62d65caa48251d9c69cc8b5a82ddfea6b014
1/*
2 * Copyright 2010-2012, The Android Open Source Project
3 *
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
17#include "slang_backend.h"
18
19#include <string>
20#include <vector>
21#include <iostream>
22
23#include "clang/AST/ASTContext.h"
24#include "clang/AST/Attr.h"
25#include "clang/AST/Decl.h"
26#include "clang/AST/DeclGroup.h"
27#include "clang/AST/RecordLayout.h"
28
29#include "clang/Basic/Diagnostic.h"
30#include "clang/Basic/TargetInfo.h"
31#include "clang/Basic/TargetOptions.h"
32
33#include "clang/CodeGen/ModuleBuilder.h"
34
35#include "clang/Frontend/CodeGenOptions.h"
36#include "clang/Frontend/FrontendDiagnostic.h"
37
38#include "llvm/ADT/Twine.h"
39#include "llvm/ADT/StringExtras.h"
40
41#include "llvm/Bitcode/ReaderWriter.h"
42
43#include "llvm/CodeGen/RegAllocRegistry.h"
44#include "llvm/CodeGen/SchedulerRegistry.h"
45
46#include "llvm/IR/Constant.h"
47#include "llvm/IR/Constants.h"
48#include "llvm/IR/DataLayout.h"
49#include "llvm/IR/DebugLoc.h"
50#include "llvm/IR/DerivedTypes.h"
51#include "llvm/IR/Function.h"
52#include "llvm/IR/IRBuilder.h"
53#include "llvm/IR/IRPrintingPasses.h"
54#include "llvm/IR/LLVMContext.h"
55#include "llvm/IR/Metadata.h"
56#include "llvm/IR/Module.h"
57
58#include "llvm/Transforms/IPO/PassManagerBuilder.h"
59
60#include "llvm/Target/TargetMachine.h"
61#include "llvm/Target/TargetOptions.h"
62#include "llvm/Support/TargetRegistry.h"
63
64#include "llvm/MC/SubtargetFeature.h"
65
66#include "slang_assert.h"
67#include "slang.h"
68#include "slang_bitcode_gen.h"
69#include "slang_rs_context.h"
70#include "slang_rs_export_foreach.h"
71#include "slang_rs_export_func.h"
72#include "slang_rs_export_reduce.h"
73#include "slang_rs_export_type.h"
74#include "slang_rs_export_var.h"
75#include "slang_rs_metadata.h"
76
77#include "rs_cc_options.h"
78
79#include "strip_unknown_attributes.h"
80
81namespace slang {
82
83void Backend::CreateFunctionPasses() {
84  if (!mPerFunctionPasses) {
85    mPerFunctionPasses = new llvm::legacy::FunctionPassManager(mpModule);
86
87    llvm::PassManagerBuilder PMBuilder;
88    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
89    PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
90  }
91}
92
93void Backend::CreateModulePasses() {
94  if (!mPerModulePasses) {
95    mPerModulePasses = new llvm::legacy::PassManager();
96
97    llvm::PassManagerBuilder PMBuilder;
98    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
99    PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
100    PMBuilder.DisableUnitAtATime = 0; // TODO Pirama confirm if this is right
101
102    if (mCodeGenOpts.UnrollLoops) {
103      PMBuilder.DisableUnrollLoops = 0;
104    } else {
105      PMBuilder.DisableUnrollLoops = 1;
106    }
107
108    PMBuilder.populateModulePassManager(*mPerModulePasses);
109    // Add a pass to strip off unknown/unsupported attributes.
110    mPerModulePasses->add(createStripUnknownAttributesPass());
111  }
112}
113
114bool Backend::CreateCodeGenPasses() {
115  if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object))
116    return true;
117
118  // Now we add passes for code emitting
119  if (mCodeGenPasses) {
120    return true;
121  } else {
122    mCodeGenPasses = new llvm::legacy::FunctionPassManager(mpModule);
123  }
124
125  // Create the TargetMachine for generating code.
126  std::string Triple = mpModule->getTargetTriple();
127
128  std::string Error;
129  const llvm::Target* TargetInfo =
130      llvm::TargetRegistry::lookupTarget(Triple, Error);
131  if (TargetInfo == nullptr) {
132    mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
133    return false;
134  }
135
136  // Target Machine Options
137  llvm::TargetOptions Options;
138
139  // Use soft-float ABI for ARM (which is the target used by Slang during code
140  // generation).  Codegen still uses hardware FPU by default.  To use software
141  // floating point, add 'soft-float' feature to FeaturesStr below.
142  Options.FloatABIType = llvm::FloatABI::Soft;
143
144  // BCC needs all unknown symbols resolved at compilation time. So we don't
145  // need any relocation model.
146  llvm::Reloc::Model RM = llvm::Reloc::Static;
147
148  // This is set for the linker (specify how large of the virtual addresses we
149  // can access for all unknown symbols.)
150  llvm::CodeModel::Model CM;
151  if (mpModule->getDataLayout().getPointerSize() == 4) {
152    CM = llvm::CodeModel::Small;
153  } else {
154    // The target may have pointer size greater than 32 (e.g. x86_64
155    // architecture) may need large data address model
156    CM = llvm::CodeModel::Medium;
157  }
158
159  // Setup feature string
160  std::string FeaturesStr;
161  if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
162    llvm::SubtargetFeatures Features;
163
164    for (std::vector<std::string>::const_iterator
165             I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
166         I != E;
167         I++)
168      Features.AddFeature(*I);
169
170    FeaturesStr = Features.getString();
171  }
172
173  llvm::TargetMachine *TM =
174    TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
175                                    Options, RM, CM);
176
177  // Register allocation policy:
178  //  createFastRegisterAllocator: fast but bad quality
179  //  createGreedyRegisterAllocator: not so fast but good quality
180  llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
181                                     llvm::createFastRegisterAllocator :
182                                     llvm::createGreedyRegisterAllocator);
183
184  llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
185  if (mCodeGenOpts.OptimizationLevel == 0) {
186    OptLevel = llvm::CodeGenOpt::None;
187  } else if (mCodeGenOpts.OptimizationLevel == 3) {
188    OptLevel = llvm::CodeGenOpt::Aggressive;
189  }
190
191  llvm::TargetMachine::CodeGenFileType CGFT =
192      llvm::TargetMachine::CGFT_AssemblyFile;
193  if (mOT == Slang::OT_Object) {
194    CGFT = llvm::TargetMachine::CGFT_ObjectFile;
195  }
196  if (TM->addPassesToEmitFile(*mCodeGenPasses, mBufferOutStream,
197                              CGFT, OptLevel)) {
198    mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target);
199    return false;
200  }
201
202  return true;
203}
204
205Backend::Backend(RSContext *Context, clang::DiagnosticsEngine *DiagEngine,
206                 const RSCCOptions &Opts,
207                 const clang::HeaderSearchOptions &HeaderSearchOpts,
208                 const clang::PreprocessorOptions &PreprocessorOpts,
209                 const clang::CodeGenOptions &CodeGenOpts,
210                 const clang::TargetOptions &TargetOpts, PragmaList *Pragmas,
211                 llvm::raw_ostream *OS, Slang::OutputType OT,
212                 clang::SourceManager &SourceMgr, bool AllowRSPrefix,
213                 bool IsFilterscript)
214    : ASTConsumer(), mTargetOpts(TargetOpts), mpModule(nullptr), mpOS(OS),
215      mOT(OT), mGen(nullptr), mPerFunctionPasses(nullptr),
216      mPerModulePasses(nullptr), mCodeGenPasses(nullptr),
217      mBufferOutStream(*mpOS), mContext(Context),
218      mSourceMgr(SourceMgr), mASTPrint(Opts.mASTPrint), mAllowRSPrefix(AllowRSPrefix),
219      mIsFilterscript(IsFilterscript), mExportVarMetadata(nullptr),
220      mExportFuncMetadata(nullptr), mExportForEachNameMetadata(nullptr),
221      mExportForEachSignatureMetadata(nullptr),
222      mExportReduceMetadata(nullptr),
223      mExportTypeMetadata(nullptr), mRSObjectSlotsMetadata(nullptr),
224      mRefCount(mContext->getASTContext()),
225      mASTChecker(Context, Context->getTargetAPI(), IsFilterscript),
226      mForEachHandler(Context),
227      mLLVMContext(slang::getGlobalLLVMContext()), mDiagEngine(*DiagEngine),
228      mCodeGenOpts(CodeGenOpts), mPragmas(Pragmas) {
229  mGen = CreateLLVMCodeGen(mDiagEngine, "", HeaderSearchOpts, PreprocessorOpts,
230      mCodeGenOpts, mLLVMContext);
231}
232
233void Backend::Initialize(clang::ASTContext &Ctx) {
234  mGen->Initialize(Ctx);
235
236  mpModule = mGen->GetModule();
237}
238
239void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
240  HandleTranslationUnitPre(Ctx);
241
242  if (mASTPrint)
243    Ctx.getTranslationUnitDecl()->dump();
244
245  mGen->HandleTranslationUnit(Ctx);
246
247  // Here, we complete a translation unit (whole translation unit is now in LLVM
248  // IR). Now, interact with LLVM backend to generate actual machine code (asm
249  // or machine code, whatever.)
250
251  // Silently ignore if we weren't initialized for some reason.
252  if (!mpModule)
253    return;
254
255  llvm::Module *M = mGen->ReleaseModule();
256  if (!M) {
257    // The module has been released by IR gen on failures, do not double free.
258    mpModule = nullptr;
259    return;
260  }
261
262  slangAssert(mpModule == M &&
263              "Unexpected module change during LLVM IR generation");
264
265  // Insert #pragma information into metadata section of module
266  if (!mPragmas->empty()) {
267    llvm::NamedMDNode *PragmaMetadata =
268        mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
269    for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
270         I != E;
271         I++) {
272      llvm::SmallVector<llvm::Metadata*, 2> Pragma;
273      // Name goes first
274      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
275      // And then value
276      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
277
278      // Create MDNode and insert into PragmaMetadata
279      PragmaMetadata->addOperand(
280          llvm::MDNode::get(mLLVMContext, Pragma));
281    }
282  }
283
284  HandleTranslationUnitPost(mpModule);
285
286  // Create passes for optimization and code emission
287
288  // Create and run per-function passes
289  CreateFunctionPasses();
290  if (mPerFunctionPasses) {
291    mPerFunctionPasses->doInitialization();
292
293    for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
294         I != E;
295         I++)
296      if (!I->isDeclaration())
297        mPerFunctionPasses->run(*I);
298
299    mPerFunctionPasses->doFinalization();
300  }
301
302  // Create and run module passes
303  CreateModulePasses();
304  if (mPerModulePasses)
305    mPerModulePasses->run(*mpModule);
306
307  switch (mOT) {
308    case Slang::OT_Assembly:
309    case Slang::OT_Object: {
310      if (!CreateCodeGenPasses())
311        return;
312
313      mCodeGenPasses->doInitialization();
314
315      for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
316          I != E;
317          I++)
318        if (!I->isDeclaration())
319          mCodeGenPasses->run(*I);
320
321      mCodeGenPasses->doFinalization();
322      break;
323    }
324    case Slang::OT_LLVMAssembly: {
325      llvm::legacy::PassManager *LLEmitPM = new llvm::legacy::PassManager();
326      LLEmitPM->add(llvm::createPrintModulePass(mBufferOutStream));
327      LLEmitPM->run(*mpModule);
328      break;
329    }
330    case Slang::OT_Bitcode: {
331      writeBitcode(mBufferOutStream, *mpModule, getTargetAPI(),
332                   mCodeGenOpts.OptimizationLevel, mCodeGenOpts.getDebugInfo());
333      break;
334    }
335    case Slang::OT_Nothing: {
336      return;
337    }
338    default: {
339      slangAssert(false && "Unknown output type");
340    }
341  }
342}
343
344// Insert explicit padding fields into struct to follow the current layout.
345//
346// A similar algorithm is present in PadHelperFunctionStruct().
347void Backend::PadStruct(clang::RecordDecl* RD) {
348  // Example of padding:
349  //
350  //   // ORIGINAL CODE                   // TRANSFORMED CODE
351  //   struct foo {                       struct foo {
352  //     int a;                             int a;
353  //     // 4 bytes of padding              char <RS_PADDING_FIELD_NAME>[4];
354  //     long b;                            long b;
355  //     int c;                             int c;
356  //     // 4 bytes of (tail) padding       char <RS_PADDING_FIELD_NAME>[4];
357  //   };                                 };
358
359  // We collect all of RD's fields in a vector FieldsInfo.  We
360  // represent tail padding as an entry in the FieldsInfo vector with a
361  // null FieldDecl.
362  typedef std::pair<size_t, clang::FieldDecl*> FieldInfoType;  // (pre-field padding bytes, field)
363  std::vector<FieldInfoType> FieldsInfo;
364
365  // RenderScript is C99-based, so we only expect to see fields.  We
366  // could iterate over fields, but instead let's iterate over
367  // everything, to verify that there are only fields.
368  for (clang::Decl* D : RD->decls()) {
369    clang::FieldDecl* FD = clang::dyn_cast<clang::FieldDecl>(D);
370    slangAssert(FD && "found a non field declaration within a struct");
371    FieldsInfo.push_back(std::make_pair(size_t(0), FD));
372  }
373
374  clang::ASTContext& ASTC = mContext->getASTContext();
375
376  // ASTContext caches record layout.  We may transform the record in a way
377  // that would render this cached information incorrect.  clang does
378  // not provide any way to invalidate this cached information.  We
379  // take the following approach:
380  //
381  // 1. ASSUME that record layout has not yet been computed for RD.
382  //
383  // 2. Create a temporary clone of RD, and compute its layout.
384  //    ASSUME that we know how to clone RD in a way that copies all the
385  //    properties that are relevant to its layout.
386  //
387  // 3. Use the layout information from the temporary clone to
388  //    transform RD.
389  //
390  // NOTE: ASTContext also caches TypeInfo (see
391  //       ASTContext::getTypeInfo()).  ASSUME that inserting padding
392  //       fields doesn't change the type in any way that affects
393  //       TypeInfo.
394  //
395  // NOTE: A RecordType knows its associated RecordDecl -- so even
396  //       while we're manipulating RD, the associated RecordType
397  //       still recognizes RD as its RecordDecl.  ASSUME that we
398  //       don't do anything during our manipulation that would cause
399  //       the RecordType to be followed to RD while RD is in a
400  //       partially transformed state.
401
402  // The assumptions above may be brittle, and if they are incorrect,
403  // we may get mysterious failures.
404
405  // create a temporary clone
406  clang::RecordDecl* RDForLayout =
407      clang::RecordDecl::Create(ASTC, clang::TTK_Struct, RD->getDeclContext(),
408                                clang::SourceLocation(), clang::SourceLocation(),
409                                nullptr /* IdentifierInfo */);
410  RDForLayout->startDefinition();
411  RDForLayout->setTypeForDecl(RD->getTypeForDecl());
412  if (RD->hasAttrs())
413    RDForLayout->setAttrs(RD->getAttrs());
414  RDForLayout->completeDefinition();
415
416  // move all fields from RD to RDForLayout
417  for (const auto &info : FieldsInfo) {
418    RD->removeDecl(info.second);
419    info.second->setLexicalDeclContext(RDForLayout);
420    RDForLayout->addDecl(info.second);
421  }
422
423  const clang::ASTRecordLayout& RL = ASTC.getASTRecordLayout(RDForLayout);
424
425  // An exportable type cannot contain a bitfield.  However, it's
426  // possible that this current type might have a bitfield and yet
427  // share a common initial sequence with an exportable type, so even
428  // if the current type has a bitfield, the current type still
429  // needs to have explicit padding inserted (in case the two types
430  // under discussion are members of a union).  We don't need to
431  // insert any padding after the bitfield, however, because that
432  // would be beyond the common initial sequence.
433  bool foundBitField = false;
434
435  // Is there any padding in this struct?
436  bool foundPadding = false;
437
438  unsigned fieldNo = 0;
439  uint64_t fieldPrePaddingOffset = 0;  // byte offset of pre-field padding within struct
440  for (auto &info : FieldsInfo) {
441    const clang::FieldDecl* FD = info.second;
442
443    if ((foundBitField = FD->isBitField()))
444      break;
445
446    const uint64_t fieldOffset = RL.getFieldOffset(fieldNo) >> 3;
447    const size_t prePadding = fieldOffset - fieldPrePaddingOffset;
448    foundPadding |= (prePadding != 0);
449    info.first = prePadding;
450
451    // get ready for the next field
452    //
453    //   assumes that getTypeSize() is the storage size of the Type -- for example,
454    //   that it includes a struct's tail padding (if any)
455    //
456    fieldPrePaddingOffset = fieldOffset + (ASTC.getTypeSize(FD->getType()) >> 3);
457    ++fieldNo;
458  }
459
460  if (!foundBitField) {
461    // In order to ensure that the front end (including reflected
462    // code) and back end agree on struct size (not just field
463    // offsets) we may need to add explicit tail padding, just as we'e
464    // added explicit padding between fields.
465    slangAssert(RL.getSize().getQuantity() >= fieldPrePaddingOffset);
466    if (const size_t tailPadding = RL.getSize().getQuantity() - fieldPrePaddingOffset) {
467      foundPadding = true;
468      FieldsInfo.push_back(std::make_pair(tailPadding, nullptr));
469    }
470  }
471
472  if (false /* change to "true" for extra debugging output */) {
473   if (foundPadding) {
474     std::cout << "PadStruct(" << RD->getNameAsString() << "):" << std::endl;
475     for (const auto &info : FieldsInfo)
476       std::cout << "  " << info.first << ", " << (info.second ? info.second->getNameAsString() : "<tail>") << std::endl;
477   }
478  }
479
480  if (foundPadding && Slang::IsLocInRSHeaderFile(RD->getLocation(), mSourceMgr)) {
481    mContext->ReportError(RD->getLocation(), "system structure contains padding: '%0'")
482        << RD->getName();
483  }
484
485  // now move fields from RDForLayout to RD, and add any necessary
486  // padding fields
487  const clang::QualType byteType = ASTC.getIntTypeForBitwidth(8, false /* not signed */);
488  clang::IdentifierInfo* const paddingIdentifierInfo = &ASTC.Idents.get(RS_PADDING_FIELD_NAME);
489  for (const auto &info : FieldsInfo) {
490    if (info.first != 0) {
491      // Create a padding field: "char <RS_PADDING_FIELD_NAME>[<info.first>];"
492
493      // TODO: Do we need to do anything else to keep this field from being shown in debugger?
494      //       There's no source location, and the field is marked as implicit.
495      const clang::QualType paddingType =
496          ASTC.getConstantArrayType(byteType,
497                                    llvm::APInt(sizeof(info.first) << 3, info.first),
498                                    clang::ArrayType::Normal, 0 /* IndexTypeQuals */);
499      clang::FieldDecl* const FD =
500          clang::FieldDecl::Create(ASTC, RD, clang::SourceLocation(), clang::SourceLocation(),
501                                   paddingIdentifierInfo,
502                                   paddingType,
503                                   nullptr,  // TypeSourceInfo*
504                                   nullptr,  // BW (bitwidth)
505                                   false,    // Mutable = false
506                                   clang::ICIS_NoInit);
507      FD->setImplicit(true);
508      RD->addDecl(FD);
509    }
510    if (info.second != nullptr) {
511      RDForLayout->removeDecl(info.second);
512      info.second->setLexicalDeclContext(RD);
513      RD->addDecl(info.second);
514    }
515  }
516
517  // There does not appear to be any safe way to delete a RecordDecl
518  // -- for example, there is no RecordDecl destructor to invalidate
519  // cached record layout, and if we were to get unlucky, some future
520  // RecordDecl could be allocated in the same place as a deleted
521  // RDForLayout and "inherit" the cached record layout from
522  // RDForLayout.
523}
524
525void Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
526  // we want to insert explicit padding fields into structs per http://b/29154200 and http://b/28070272
527  switch (D->getTagKind()) {
528    case clang::TTK_Struct:
529      PadStruct(llvm::cast<clang::RecordDecl>(D));
530      break;
531
532    case clang::TTK_Union:
533      // cannot be part of an exported type
534      break;
535
536    case clang::TTK_Enum:
537      // a scalar
538      break;
539
540    case clang::TTK_Class:
541    case clang::TTK_Interface:
542    default:
543      slangAssert(false && "Unexpected TagTypeKind");
544      break;
545  }
546  mGen->HandleTagDeclDefinition(D);
547}
548
549void Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
550  mGen->CompleteTentativeDefinition(D);
551}
552
553Backend::~Backend() {
554  delete mpModule;
555  delete mGen;
556  delete mPerFunctionPasses;
557  delete mPerModulePasses;
558  delete mCodeGenPasses;
559}
560
561// 1) Add zero initialization of local RS object types
562void Backend::AnnotateFunction(clang::FunctionDecl *FD) {
563  if (FD &&
564      FD->hasBody() &&
565      !FD->isImplicit() &&
566      !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
567    mRefCount.Init();
568    mRefCount.SetDeclContext(FD);
569    mRefCount.Visit(FD->getBody());
570  }
571}
572
573bool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
574  // Find and remember the types for rs_allocation and rs_script_call_t so
575  // they can be used later for translating rsForEach() calls.
576  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
577       (mContext->getAllocationType().isNull() ||
578        mContext->getScriptCallType().isNull()) &&
579       I != E; I++) {
580    if (clang::TypeDecl* TD = llvm::dyn_cast<clang::TypeDecl>(*I)) {
581      clang::StringRef TypeName = TD->getName();
582      if (TypeName.equals("rs_allocation")) {
583        mContext->setAllocationType(TD);
584      } else if (TypeName.equals("rs_script_call_t")) {
585        mContext->setScriptCallType(TD);
586      }
587    }
588  }
589
590  // Disallow user-defined functions with prefix "rs"
591  if (!mAllowRSPrefix) {
592    // Iterate all function declarations in the program.
593    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
594         I != E; I++) {
595      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
596      if (FD == nullptr)
597        continue;
598      if (!FD->getName().startswith("rs"))  // Check prefix
599        continue;
600      if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
601        mContext->ReportError(FD->getLocation(),
602                              "invalid function name prefix, "
603                              "\"rs\" is reserved: '%0'")
604            << FD->getName();
605    }
606  }
607
608  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
609    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
610    if (FD) {
611      // Handle forward reference from pragma (see
612      // RSReducePragmaHandler::HandlePragma for backward reference).
613      mContext->markUsedByReducePragma(FD, RSContext::CheckNameYes);
614      if (FD->isGlobal()) {
615        // Check that we don't have any array parameters being misinterpreted as
616        // kernel pointers due to the C type system's array to pointer decay.
617        size_t numParams = FD->getNumParams();
618        for (size_t i = 0; i < numParams; i++) {
619          const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
620          clang::QualType QT = PVD->getOriginalType();
621          if (QT->isArrayType()) {
622            mContext->ReportError(
623                PVD->getTypeSpecStartLoc(),
624                "exported function parameters may not have array type: %0")
625                << QT;
626          }
627        }
628        AnnotateFunction(FD);
629      }
630    }
631
632    if (getTargetAPI() >= SLANG_FEATURE_SINGLE_SOURCE_API) {
633      if (FD && FD->hasBody() && !FD->isImplicit() &&
634          !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
635        if (FD->hasAttr<clang::RenderScriptKernelAttr>()) {
636          // Log functions with attribute "kernel" by their names, and assign
637          // them slot numbers. Any other function cannot be used in a
638          // rsForEach() or rsForEachWithOptions() call, including old-style
639          // kernel functions which are defined without the "kernel" attribute.
640          mContext->addForEach(FD);
641        }
642        // Look for any kernel launch calls and translate them into using the
643        // internal API.
644        // Report a compiler error on kernel launches inside a kernel.
645        mForEachHandler.handleForEachCalls(FD, getTargetAPI());
646      }
647    }
648  }
649
650  return mGen->HandleTopLevelDecl(D);
651}
652
653void Backend::HandleTranslationUnitPre(clang::ASTContext &C) {
654  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
655
656  if (!mContext->processReducePragmas(this))
657    return;
658
659  // If we have an invalid RS/FS AST, don't check further.
660  if (!mASTChecker.Validate()) {
661    return;
662  }
663
664  if (mIsFilterscript) {
665    mContext->addPragma("rs_fp_relaxed", "");
666  }
667
668  int version = mContext->getVersion();
669  if (version == 0) {
670    // Not setting a version is an error
671    mDiagEngine.Report(
672        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
673        mDiagEngine.getCustomDiagID(
674            clang::DiagnosticsEngine::Error,
675            "missing pragma for version in source file"));
676  } else {
677    slangAssert(version == 1);
678  }
679
680  if (mContext->getReflectJavaPackageName().empty()) {
681    mDiagEngine.Report(
682        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
683        mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
684                                    "missing \"#pragma rs "
685                                    "java_package_name(com.foo.bar)\" "
686                                    "in source file"));
687    return;
688  }
689
690  // Create a static global destructor if necessary (to handle RS object
691  // runtime cleanup).
692  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
693  if (FD) {
694    HandleTopLevelDecl(clang::DeclGroupRef(FD));
695  }
696
697  // Process any static function declarations
698  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
699          E = TUDecl->decls_end(); I != E; I++) {
700    if ((I->getKind() >= clang::Decl::firstFunction) &&
701        (I->getKind() <= clang::Decl::lastFunction)) {
702      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
703      if (FD && !FD->isGlobal()) {
704        AnnotateFunction(FD);
705      }
706    }
707  }
708}
709
710///////////////////////////////////////////////////////////////////////////////
711void Backend::dumpExportVarInfo(llvm::Module *M) {
712  int slotCount = 0;
713  if (mExportVarMetadata == nullptr)
714    mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
715
716  llvm::SmallVector<llvm::Metadata *, 2> ExportVarInfo;
717
718  // We emit slot information (#rs_object_slots) for any reference counted
719  // RS type or pointer (which can also be bound).
720
721  for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
722          E = mContext->export_vars_end();
723       I != E;
724       I++) {
725    const RSExportVar *EV = *I;
726    const RSExportType *ET = EV->getType();
727    bool countsAsRSObject = false;
728
729    // Variable name
730    ExportVarInfo.push_back(
731        llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
732
733    // Type name
734    switch (ET->getClass()) {
735      case RSExportType::ExportClassPrimitive: {
736        const RSExportPrimitiveType *PT =
737            static_cast<const RSExportPrimitiveType*>(ET);
738        ExportVarInfo.push_back(
739            llvm::MDString::get(
740              mLLVMContext, llvm::utostr(PT->getType())));
741        if (PT->isRSObjectType()) {
742          countsAsRSObject = true;
743        }
744        break;
745      }
746      case RSExportType::ExportClassPointer: {
747        ExportVarInfo.push_back(
748            llvm::MDString::get(
749              mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
750                ->getPointeeType()->getName()).c_str()));
751        break;
752      }
753      case RSExportType::ExportClassMatrix: {
754        ExportVarInfo.push_back(
755            llvm::MDString::get(
756              mLLVMContext, llvm::utostr(
757                  /* TODO Strange value.  This pushes just a number, quite
758                   * different than the other cases.  What is this used for?
759                   * These are the metadata values that some partner drivers
760                   * want to reference (for TBAA, etc.). We may want to look
761                   * at whether these provide any reasonable value (or have
762                   * distinct enough values to actually depend on).
763                   */
764                DataTypeRSMatrix2x2 +
765                static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
766        break;
767      }
768      case RSExportType::ExportClassVector:
769      case RSExportType::ExportClassConstantArray:
770      case RSExportType::ExportClassRecord: {
771        ExportVarInfo.push_back(
772            llvm::MDString::get(mLLVMContext,
773              EV->getType()->getName().c_str()));
774        break;
775      }
776    }
777
778    mExportVarMetadata->addOperand(
779        llvm::MDNode::get(mLLVMContext, ExportVarInfo));
780    ExportVarInfo.clear();
781
782    if (mRSObjectSlotsMetadata == nullptr) {
783      mRSObjectSlotsMetadata =
784          M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
785    }
786
787    if (countsAsRSObject) {
788      mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
789          llvm::MDString::get(mLLVMContext, llvm::utostr(slotCount))));
790    }
791
792    slotCount++;
793  }
794}
795
796// A similar algorithm is present in Backend::PadStruct().
797static void PadHelperFunctionStruct(llvm::Module *M,
798                                    llvm::StructType **paddedStructType,
799                                    std::vector<unsigned> *origFieldNumToPaddedFieldNum,
800                                    llvm::StructType *origStructType) {
801  slangAssert(origFieldNumToPaddedFieldNum->empty());
802  origFieldNumToPaddedFieldNum->resize(2 * origStructType->getNumElements());
803
804  llvm::LLVMContext &llvmContext = M->getContext();
805
806  const llvm::DataLayout *DL = &M->getDataLayout();
807  const llvm::StructLayout *SL = DL->getStructLayout(origStructType);
808
809  // Field types -- including any padding fields we need to insert.
810  std::vector<llvm::Type *> paddedFieldTypes;
811  paddedFieldTypes.reserve(2 * origStructType->getNumElements());
812
813  // Is there any padding in this struct?
814  bool foundPadding = false;
815
816  llvm::Type *const byteType = llvm::Type::getInt8Ty(llvmContext);
817  unsigned origFieldNum = 0, paddedFieldNum = 0;
818  uint64_t fieldPrePaddingOffset = 0;  // byte offset of pre-field padding within struct
819  for (llvm::Type *fieldType : origStructType->elements()) {
820    const uint64_t fieldOffset = SL->getElementOffset(origFieldNum);
821    const size_t prePadding = fieldOffset - fieldPrePaddingOffset;
822    if (prePadding != 0) {
823      foundPadding = true;
824      paddedFieldTypes.push_back(llvm::ArrayType::get(byteType, prePadding));
825      ++paddedFieldNum;
826    }
827    paddedFieldTypes.push_back(fieldType);
828    (*origFieldNumToPaddedFieldNum)[origFieldNum] = paddedFieldNum;
829
830    // get ready for the next field
831    fieldPrePaddingOffset = fieldOffset + DL->getTypeAllocSize(fieldType);
832    ++origFieldNum;
833    ++paddedFieldNum;
834  }
835
836  // In order to ensure that the front end (including reflected code)
837  // and back end agree on struct size (not just field offsets) we may
838  // need to add explicit tail padding, just as we'e added explicit
839  // padding between fields.
840  slangAssert(SL->getSizeInBytes() >= fieldPrePaddingOffset);
841  if (const size_t tailPadding = SL->getSizeInBytes() - fieldPrePaddingOffset) {
842    foundPadding = true;
843    paddedFieldTypes.push_back(llvm::ArrayType::get(byteType, tailPadding));
844  }
845
846  *paddedStructType = (foundPadding
847                       ? llvm::StructType::get(llvmContext, paddedFieldTypes)
848                       : origStructType);
849}
850
851void Backend::dumpExportFunctionInfo(llvm::Module *M) {
852  if (mExportFuncMetadata == nullptr)
853    mExportFuncMetadata =
854        M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
855
856  llvm::SmallVector<llvm::Metadata *, 1> ExportFuncInfo;
857
858  for (RSContext::const_export_func_iterator
859          I = mContext->export_funcs_begin(),
860          E = mContext->export_funcs_end();
861       I != E;
862       I++) {
863    const RSExportFunc *EF = *I;
864
865    // Function name
866    if (!EF->hasParam()) {
867      ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
868                                                   EF->getName().c_str()));
869    } else {
870      llvm::Function *F = M->getFunction(EF->getName());
871      llvm::Function *HelperFunction;
872      const std::string HelperFunctionName(".helper_" + EF->getName());
873
874      slangAssert(F && "Function marked as exported disappeared in Bitcode");
875
876      // Create helper function
877      {
878        llvm::StructType *OrigHelperFunctionParameterTy = nullptr;
879        llvm::StructType *PaddedHelperFunctionParameterTy = nullptr;
880
881        std::vector<unsigned> OrigFieldNumToPaddedFieldNum;
882        std::vector<bool> isStructInput;
883
884        if (!F->getArgumentList().empty()) {
885          std::vector<llvm::Type*> HelperFunctionParameterTys;
886          for (llvm::Function::arg_iterator AI = F->arg_begin(),
887                   AE = F->arg_end(); AI != AE; AI++) {
888              if (AI->getType()->isPointerTy() && AI->getType()->getPointerElementType()->isStructTy()) {
889                  HelperFunctionParameterTys.push_back(AI->getType()->getPointerElementType());
890                  isStructInput.push_back(true);
891              } else {
892                  HelperFunctionParameterTys.push_back(AI->getType());
893                  isStructInput.push_back(false);
894              }
895          }
896          OrigHelperFunctionParameterTy =
897              llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
898          PadHelperFunctionStruct(M,
899                                  &PaddedHelperFunctionParameterTy, &OrigFieldNumToPaddedFieldNum,
900                                  OrigHelperFunctionParameterTy);
901        }
902
903        if (!EF->checkParameterPacketType(OrigHelperFunctionParameterTy)) {
904          fprintf(stderr, "Failed to export function %s: parameter type "
905                          "mismatch during creation of helper function.\n",
906                  EF->getName().c_str());
907
908          const RSExportRecordType *Expected = EF->getParamPacketType();
909          if (Expected) {
910            fprintf(stderr, "Expected:\n");
911            Expected->getLLVMType()->dump();
912          }
913          if (OrigHelperFunctionParameterTy) {
914            fprintf(stderr, "Got:\n");
915            OrigHelperFunctionParameterTy->dump();
916          }
917        }
918
919        std::vector<llvm::Type*> Params;
920        if (PaddedHelperFunctionParameterTy) {
921          llvm::PointerType *HelperFunctionParameterTyP =
922              llvm::PointerType::getUnqual(PaddedHelperFunctionParameterTy);
923          Params.push_back(HelperFunctionParameterTyP);
924        }
925
926        llvm::FunctionType * HelperFunctionType =
927            llvm::FunctionType::get(F->getReturnType(),
928                                    Params,
929                                    /* IsVarArgs = */false);
930
931        HelperFunction =
932            llvm::Function::Create(HelperFunctionType,
933                                   llvm::GlobalValue::ExternalLinkage,
934                                   HelperFunctionName,
935                                   M);
936
937        HelperFunction->addFnAttr(llvm::Attribute::NoInline);
938        HelperFunction->setCallingConv(F->getCallingConv());
939
940        // Create helper function body
941        {
942          llvm::Argument *HelperFunctionParameter =
943              &(*HelperFunction->arg_begin());
944          llvm::BasicBlock *BB =
945              llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
946          llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
947          llvm::SmallVector<llvm::Value*, 6> Params;
948          llvm::Value *Idx[2];
949
950          Idx[0] =
951              llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
952
953          // getelementptr and load instruction for all elements in
954          // parameter .p
955          for (size_t origFieldNum = 0; origFieldNum < EF->getNumParameters(); origFieldNum++) {
956            // getelementptr
957            Idx[1] = llvm::ConstantInt::get(
958              llvm::Type::getInt32Ty(mLLVMContext), OrigFieldNumToPaddedFieldNum[origFieldNum]);
959
960            llvm::Value *Ptr = NULL;
961
962            Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
963
964            // Load is only required for non-struct ptrs
965            if (isStructInput[origFieldNum]) {
966                Params.push_back(Ptr);
967            } else {
968                llvm::Value *V = IB->CreateLoad(Ptr);
969                Params.push_back(V);
970            }
971          }
972
973          // Call and pass the all elements as parameter to F
974          llvm::CallInst *CI = IB->CreateCall(F, Params);
975
976          CI->setCallingConv(F->getCallingConv());
977
978          if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext)) {
979            IB->CreateRetVoid();
980          } else {
981            IB->CreateRet(CI);
982          }
983
984          delete IB;
985        }
986      }
987
988      ExportFuncInfo.push_back(
989          llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
990    }
991
992    mExportFuncMetadata->addOperand(
993        llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
994    ExportFuncInfo.clear();
995  }
996}
997
998void Backend::dumpExportForEachInfo(llvm::Module *M) {
999  if (mExportForEachNameMetadata == nullptr) {
1000    mExportForEachNameMetadata =
1001        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
1002  }
1003  if (mExportForEachSignatureMetadata == nullptr) {
1004    mExportForEachSignatureMetadata =
1005        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
1006  }
1007
1008  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachName;
1009  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachInfo;
1010
1011  for (RSContext::const_export_foreach_iterator
1012          I = mContext->export_foreach_begin(),
1013          E = mContext->export_foreach_end();
1014       I != E;
1015       I++) {
1016    const RSExportForEach *EFE = *I;
1017
1018    ExportForEachName.push_back(
1019        llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
1020
1021    mExportForEachNameMetadata->addOperand(
1022        llvm::MDNode::get(mLLVMContext, ExportForEachName));
1023    ExportForEachName.clear();
1024
1025    ExportForEachInfo.push_back(
1026        llvm::MDString::get(mLLVMContext,
1027                            llvm::utostr(EFE->getSignatureMetadata())));
1028
1029    mExportForEachSignatureMetadata->addOperand(
1030        llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
1031    ExportForEachInfo.clear();
1032  }
1033}
1034
1035void Backend::dumpExportReduceInfo(llvm::Module *M) {
1036  if (!mExportReduceMetadata) {
1037    mExportReduceMetadata =
1038      M->getOrInsertNamedMetadata(RS_EXPORT_REDUCE_MN);
1039  }
1040
1041  llvm::SmallVector<llvm::Metadata *, 6> ExportReduceInfo;
1042  // Add operand to ExportReduceInfo, padding out missing operands with
1043  // nullptr.
1044  auto addOperand = [&ExportReduceInfo](uint32_t Idx, llvm::Metadata *N) {
1045    while (Idx > ExportReduceInfo.size())
1046      ExportReduceInfo.push_back(nullptr);
1047    ExportReduceInfo.push_back(N);
1048  };
1049  // Add string operand to ExportReduceInfo, padding out missing operands
1050  // with nullptr.
1051  // If string is empty, then do not add it unless Always is true.
1052  auto addString = [&addOperand, this](uint32_t Idx, const std::string &S,
1053                                       bool Always = true) {
1054    if (Always || !S.empty())
1055      addOperand(Idx, llvm::MDString::get(mLLVMContext, S));
1056  };
1057
1058  // Add the description of the reduction kernels to the metadata node.
1059  for (auto I = mContext->export_reduce_begin(),
1060            E = mContext->export_reduce_end();
1061       I != E; ++I) {
1062    ExportReduceInfo.clear();
1063
1064    int Idx = 0;
1065
1066    addString(Idx++, (*I)->getNameReduce());
1067
1068    addOperand(Idx++, llvm::MDString::get(mLLVMContext, llvm::utostr((*I)->getAccumulatorTypeSize())));
1069
1070    llvm::SmallVector<llvm::Metadata *, 2> Accumulator;
1071    Accumulator.push_back(
1072      llvm::MDString::get(mLLVMContext, (*I)->getNameAccumulator()));
1073    Accumulator.push_back(llvm::MDString::get(
1074      mLLVMContext,
1075      llvm::utostr((*I)->getAccumulatorSignatureMetadata())));
1076    addOperand(Idx++, llvm::MDTuple::get(mLLVMContext, Accumulator));
1077
1078    addString(Idx++, (*I)->getNameInitializer(), false);
1079    addString(Idx++, (*I)->getNameCombiner(), false);
1080    addString(Idx++, (*I)->getNameOutConverter(), false);
1081    addString(Idx++, (*I)->getNameHalter(), false);
1082
1083    mExportReduceMetadata->addOperand(
1084      llvm::MDTuple::get(mLLVMContext, ExportReduceInfo));
1085  }
1086}
1087
1088void Backend::dumpExportTypeInfo(llvm::Module *M) {
1089  llvm::SmallVector<llvm::Metadata *, 1> ExportTypeInfo;
1090
1091  for (RSContext::const_export_type_iterator
1092          I = mContext->export_types_begin(),
1093          E = mContext->export_types_end();
1094       I != E;
1095       I++) {
1096    // First, dump type name list to export
1097    const RSExportType *ET = I->getValue();
1098
1099    ExportTypeInfo.clear();
1100    // Type name
1101    ExportTypeInfo.push_back(
1102        llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
1103
1104    if (ET->getClass() == RSExportType::ExportClassRecord) {
1105      const RSExportRecordType *ERT =
1106          static_cast<const RSExportRecordType*>(ET);
1107
1108      if (mExportTypeMetadata == nullptr)
1109        mExportTypeMetadata =
1110            M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
1111
1112      mExportTypeMetadata->addOperand(
1113          llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
1114
1115      // Now, export struct field information to %[struct name]
1116      std::string StructInfoMetadataName("%");
1117      StructInfoMetadataName.append(ET->getName());
1118      llvm::NamedMDNode *StructInfoMetadata =
1119          M->getOrInsertNamedMetadata(StructInfoMetadataName);
1120      llvm::SmallVector<llvm::Metadata *, 3> FieldInfo;
1121
1122      slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
1123                  "Metadata with same name was created before");
1124      for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
1125              FE = ERT->fields_end();
1126           FI != FE;
1127           FI++) {
1128        const RSExportRecordType::Field *F = *FI;
1129
1130        // 1. field name
1131        FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
1132                                                F->getName().c_str()));
1133
1134        // 2. field type name
1135        FieldInfo.push_back(
1136            llvm::MDString::get(mLLVMContext,
1137                                F->getType()->getName().c_str()));
1138
1139        StructInfoMetadata->addOperand(
1140            llvm::MDNode::get(mLLVMContext, FieldInfo));
1141        FieldInfo.clear();
1142      }
1143    }   // ET->getClass() == RSExportType::ExportClassRecord
1144  }
1145}
1146
1147void Backend::HandleTranslationUnitPost(llvm::Module *M) {
1148
1149  if (!mContext->is64Bit()) {
1150    M->setDataLayout("e-p:32:32-i64:64-v128:64:128-n32-S64");
1151  }
1152
1153  if (!mContext->processExports())
1154    return;
1155
1156  if (mContext->hasExportVar())
1157    dumpExportVarInfo(M);
1158
1159  if (mContext->hasExportFunc())
1160    dumpExportFunctionInfo(M);
1161
1162  if (mContext->hasExportForEach())
1163    dumpExportForEachInfo(M);
1164
1165  if (mContext->hasExportReduce())
1166    dumpExportReduceInfo(M);
1167
1168  if (mContext->hasExportType())
1169    dumpExportTypeInfo(M);
1170}
1171
1172}  // namespace slang
1173