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 22 #include "clang/AST/ASTContext.h" 23 #include "clang/AST/Attr.h" 24 #include "clang/AST/Decl.h" 25 #include "clang/AST/DeclGroup.h" 26 27 #include "clang/Basic/Diagnostic.h" 28 #include "clang/Basic/TargetInfo.h" 29 #include "clang/Basic/TargetOptions.h" 30 31 #include "clang/CodeGen/ModuleBuilder.h" 32 33 #include "clang/Frontend/CodeGenOptions.h" 34 #include "clang/Frontend/FrontendDiagnostic.h" 35 36 #include "llvm/ADT/Twine.h" 37 #include "llvm/ADT/StringExtras.h" 38 39 #include "llvm/Bitcode/ReaderWriter.h" 40 41 #include "llvm/CodeGen/RegAllocRegistry.h" 42 #include "llvm/CodeGen/SchedulerRegistry.h" 43 44 #include "llvm/IR/Constant.h" 45 #include "llvm/IR/Constants.h" 46 #include "llvm/IR/DataLayout.h" 47 #include "llvm/IR/DebugLoc.h" 48 #include "llvm/IR/DerivedTypes.h" 49 #include "llvm/IR/Function.h" 50 #include "llvm/IR/IRBuilder.h" 51 #include "llvm/IR/IRPrintingPasses.h" 52 #include "llvm/IR/LLVMContext.h" 53 #include "llvm/IR/Metadata.h" 54 #include "llvm/IR/Module.h" 55 56 #include "llvm/Transforms/IPO/PassManagerBuilder.h" 57 58 #include "llvm/Target/TargetMachine.h" 59 #include "llvm/Target/TargetOptions.h" 60 #include "llvm/Support/TargetRegistry.h" 61 62 #include "llvm/MC/SubtargetFeature.h" 63 64 #include "slang_assert.h" 65 #include "slang.h" 66 #include "slang_bitcode_gen.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_reduce.h" 71 #include "slang_rs_export_type.h" 72 #include "slang_rs_export_var.h" 73 #include "slang_rs_metadata.h" 74 75 #include "rs_cc_options.h" 76 77 #include "strip_unknown_attributes.h" 78 79 namespace slang { 80 81 void Backend::CreateFunctionPasses() { 82 if (!mPerFunctionPasses) { 83 mPerFunctionPasses = new llvm::legacy::FunctionPassManager(mpModule); 84 85 llvm::PassManagerBuilder PMBuilder; 86 PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel; 87 PMBuilder.populateFunctionPassManager(*mPerFunctionPasses); 88 } 89 } 90 91 void Backend::CreateModulePasses() { 92 if (!mPerModulePasses) { 93 mPerModulePasses = new llvm::legacy::PassManager(); 94 95 llvm::PassManagerBuilder PMBuilder; 96 PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel; 97 PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize; 98 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 110 PMBuilder.populateModulePassManager(*mPerModulePasses); 111 // Add a pass to strip off unknown/unsupported attributes. 112 mPerModulePasses->add(createStripUnknownAttributesPass()); 113 } 114 } 115 116 bool Backend::CreateCodeGenPasses() { 117 if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object)) 118 return true; 119 120 // Now we add passes for code emitting 121 if (mCodeGenPasses) { 122 return true; 123 } else { 124 mCodeGenPasses = new llvm::legacy::FunctionPassManager(mpModule); 125 } 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); 133 if (TargetInfo == nullptr) { 134 mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error; 135 return false; 136 } 137 138 // Target Machine Options 139 llvm::TargetOptions Options; 140 141 // Use soft-float ABI for ARM (which is the target used by Slang during code 142 // generation). Codegen still uses hardware FPU by default. To use software 143 // floating point, add 'soft-float' feature to FeaturesStr below. 144 Options.FloatABIType = llvm::FloatABI::Soft; 145 146 // BCC needs all unknown symbols resolved at compilation time. So we don't 147 // need any relocation model. 148 llvm::Reloc::Model RM = llvm::Reloc::Static; 149 150 // This is set for the linker (specify how large of the virtual addresses we 151 // can access for all unknown symbols.) 152 llvm::CodeModel::Model CM; 153 if (mpModule->getDataLayout().getPointerSize() == 4) { 154 CM = llvm::CodeModel::Small; 155 } else { 156 // The target may have pointer size greater than 32 (e.g. x86_64 157 // architecture) may need large data address model 158 CM = llvm::CodeModel::Medium; 159 } 160 161 // Setup feature string 162 std::string FeaturesStr; 163 if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) { 164 llvm::SubtargetFeatures Features; 165 166 for (std::vector<std::string>::const_iterator 167 I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end(); 168 I != E; 169 I++) 170 Features.AddFeature(*I); 171 172 FeaturesStr = Features.getString(); 173 } 174 175 llvm::TargetMachine *TM = 176 TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr, 177 Options, RM, CM); 178 179 // Register allocation policy: 180 // createFastRegisterAllocator: fast but bad quality 181 // createGreedyRegisterAllocator: not so fast but good quality 182 llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ? 183 llvm::createFastRegisterAllocator : 184 llvm::createGreedyRegisterAllocator); 185 186 llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default; 187 if (mCodeGenOpts.OptimizationLevel == 0) { 188 OptLevel = llvm::CodeGenOpt::None; 189 } else if (mCodeGenOpts.OptimizationLevel == 3) { 190 OptLevel = llvm::CodeGenOpt::Aggressive; 191 } 192 193 llvm::TargetMachine::CodeGenFileType CGFT = 194 llvm::TargetMachine::CGFT_AssemblyFile; 195 if (mOT == Slang::OT_Object) { 196 CGFT = llvm::TargetMachine::CGFT_ObjectFile; 197 } 198 if (TM->addPassesToEmitFile(*mCodeGenPasses, mBufferOutStream, 199 CGFT, OptLevel)) { 200 mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target); 201 return false; 202 } 203 204 return true; 205 } 206 207 Backend::Backend(RSContext *Context, clang::DiagnosticsEngine *DiagEngine, 208 const RSCCOptions &Opts, 209 const clang::HeaderSearchOptions &HeaderSearchOpts, 210 const clang::PreprocessorOptions &PreprocessorOpts, 211 const clang::CodeGenOptions &CodeGenOpts, 212 const clang::TargetOptions &TargetOpts, PragmaList *Pragmas, 213 llvm::raw_ostream *OS, Slang::OutputType OT, 214 clang::SourceManager &SourceMgr, bool AllowRSPrefix, 215 bool IsFilterscript) 216 : ASTConsumer(), mTargetOpts(TargetOpts), mpModule(nullptr), mpOS(OS), 217 mOT(OT), mGen(nullptr), mPerFunctionPasses(nullptr), 218 mPerModulePasses(nullptr), mCodeGenPasses(nullptr), 219 mBufferOutStream(*mpOS), mContext(Context), 220 mSourceMgr(SourceMgr), mASTPrint(Opts.mASTPrint), mAllowRSPrefix(AllowRSPrefix), 221 mIsFilterscript(IsFilterscript), mExportVarMetadata(nullptr), 222 mExportFuncMetadata(nullptr), mExportForEachNameMetadata(nullptr), 223 mExportForEachSignatureMetadata(nullptr), 224 mExportReduceMetadata(nullptr), 225 mExportTypeMetadata(nullptr), mRSObjectSlotsMetadata(nullptr), 226 mRefCount(mContext->getASTContext()), 227 mASTChecker(Context, Context->getTargetAPI(), IsFilterscript), 228 mForEachHandler(Context), 229 mLLVMContext(llvm::getGlobalContext()), mDiagEngine(*DiagEngine), 230 mCodeGenOpts(CodeGenOpts), mPragmas(Pragmas) { 231 mGen = CreateLLVMCodeGen(mDiagEngine, "", HeaderSearchOpts, PreprocessorOpts, 232 mCodeGenOpts, mLLVMContext); 233 } 234 235 void Backend::Initialize(clang::ASTContext &Ctx) { 236 mGen->Initialize(Ctx); 237 238 mpModule = mGen->GetModule(); 239 } 240 241 void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) { 242 HandleTranslationUnitPre(Ctx); 243 244 if (mASTPrint) 245 Ctx.getTranslationUnitDecl()->dump(); 246 247 mGen->HandleTranslationUnit(Ctx); 248 249 // Here, we complete a translation unit (whole translation unit is now in LLVM 250 // IR). Now, interact with LLVM backend to generate actual machine code (asm 251 // or machine code, whatever.) 252 253 // Silently ignore if we weren't initialized for some reason. 254 if (!mpModule) 255 return; 256 257 llvm::Module *M = mGen->ReleaseModule(); 258 if (!M) { 259 // The module has been released by IR gen on failures, do not double free. 260 mpModule = nullptr; 261 return; 262 } 263 264 slangAssert(mpModule == M && 265 "Unexpected module change during LLVM IR generation"); 266 267 // Insert #pragma information into metadata section of module 268 if (!mPragmas->empty()) { 269 llvm::NamedMDNode *PragmaMetadata = 270 mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName); 271 for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end(); 272 I != E; 273 I++) { 274 llvm::SmallVector<llvm::Metadata*, 2> Pragma; 275 // Name goes first 276 Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first)); 277 // And then value 278 Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second)); 279 280 // Create MDNode and insert into PragmaMetadata 281 PragmaMetadata->addOperand( 282 llvm::MDNode::get(mLLVMContext, Pragma)); 283 } 284 } 285 286 HandleTranslationUnitPost(mpModule); 287 288 // Create passes for optimization and code emission 289 290 // Create and run per-function passes 291 CreateFunctionPasses(); 292 if (mPerFunctionPasses) { 293 mPerFunctionPasses->doInitialization(); 294 295 for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end(); 296 I != E; 297 I++) 298 if (!I->isDeclaration()) 299 mPerFunctionPasses->run(*I); 300 301 mPerFunctionPasses->doFinalization(); 302 } 303 304 // Create and run module passes 305 CreateModulePasses(); 306 if (mPerModulePasses) 307 mPerModulePasses->run(*mpModule); 308 309 switch (mOT) { 310 case Slang::OT_Assembly: 311 case Slang::OT_Object: { 312 if (!CreateCodeGenPasses()) 313 return; 314 315 mCodeGenPasses->doInitialization(); 316 317 for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end(); 318 I != E; 319 I++) 320 if (!I->isDeclaration()) 321 mCodeGenPasses->run(*I); 322 323 mCodeGenPasses->doFinalization(); 324 break; 325 } 326 case Slang::OT_LLVMAssembly: { 327 llvm::legacy::PassManager *LLEmitPM = new llvm::legacy::PassManager(); 328 LLEmitPM->add(llvm::createPrintModulePass(mBufferOutStream)); 329 LLEmitPM->run(*mpModule); 330 break; 331 } 332 case Slang::OT_Bitcode: { 333 writeBitcode(mBufferOutStream, *mpModule, getTargetAPI(), 334 mCodeGenOpts.OptimizationLevel, mCodeGenOpts.getDebugInfo()); 335 break; 336 } 337 case Slang::OT_Nothing: { 338 return; 339 } 340 default: { 341 slangAssert(false && "Unknown output type"); 342 } 343 } 344 } 345 346 void Backend::HandleTagDeclDefinition(clang::TagDecl *D) { 347 mGen->HandleTagDeclDefinition(D); 348 } 349 350 void Backend::CompleteTentativeDefinition(clang::VarDecl *D) { 351 mGen->CompleteTentativeDefinition(D); 352 } 353 354 Backend::~Backend() { 355 delete mpModule; 356 delete mGen; 357 delete mPerFunctionPasses; 358 delete mPerModulePasses; 359 delete mCodeGenPasses; 360 } 361 362 // 1) Add zero initialization of local RS object types 363 void Backend::AnnotateFunction(clang::FunctionDecl *FD) { 364 if (FD && 365 FD->hasBody() && 366 !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) { 367 mRefCount.Init(); 368 mRefCount.SetDeclContext(FD); 369 mRefCount.Visit(FD->getBody()); 370 } 371 } 372 373 bool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) { 374 // Find and remember the types for rs_allocation and rs_script_call_t so 375 // they can be used later for translating rsForEach() calls. 376 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); 377 (mContext->getAllocationType().isNull() || 378 mContext->getScriptCallType().isNull()) && 379 I != E; I++) { 380 if (clang::TypeDecl* TD = llvm::dyn_cast<clang::TypeDecl>(*I)) { 381 clang::StringRef TypeName = TD->getName(); 382 if (TypeName.equals("rs_allocation")) { 383 mContext->setAllocationType(TD); 384 } else if (TypeName.equals("rs_script_call_t")) { 385 mContext->setScriptCallType(TD); 386 } 387 } 388 } 389 390 // Disallow user-defined functions with prefix "rs" 391 if (!mAllowRSPrefix) { 392 // Iterate all function declarations in the program. 393 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); 394 I != E; I++) { 395 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I); 396 if (FD == nullptr) 397 continue; 398 if (!FD->getName().startswith("rs")) // Check prefix 399 continue; 400 if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) 401 mContext->ReportError(FD->getLocation(), 402 "invalid function name prefix, " 403 "\"rs\" is reserved: '%0'") 404 << FD->getName(); 405 } 406 } 407 408 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) { 409 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I); 410 if (FD) { 411 // Handle forward reference from pragma (see 412 // RSReducePragmaHandler::HandlePragma for backward reference). 413 mContext->markUsedByReducePragma(FD, RSContext::CheckNameYes); 414 if (FD->isGlobal()) { 415 // Check that we don't have any array parameters being misinterpreted as 416 // kernel pointers due to the C type system's array to pointer decay. 417 size_t numParams = FD->getNumParams(); 418 for (size_t i = 0; i < numParams; i++) { 419 const clang::ParmVarDecl *PVD = FD->getParamDecl(i); 420 clang::QualType QT = PVD->getOriginalType(); 421 if (QT->isArrayType()) { 422 mContext->ReportError( 423 PVD->getTypeSpecStartLoc(), 424 "exported function parameters may not have array type: %0") 425 << QT; 426 } 427 } 428 AnnotateFunction(FD); 429 } 430 } 431 432 if (getTargetAPI() >= SLANG_FEATURE_SINGLE_SOURCE_API) { 433 if (FD && FD->hasBody() && 434 !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) { 435 if (FD->hasAttr<clang::KernelAttr>()) { 436 // Log functions with attribute "kernel" by their names, and assign 437 // them slot numbers. Any other function cannot be used in a 438 // rsForEach() or rsForEachWithOptions() call, including old-style 439 // kernel functions which are defined without the "kernel" attribute. 440 mContext->addForEach(FD); 441 } 442 // Look for any kernel launch calls and translate them into using the 443 // internal API. 444 // Report a compiler error on kernel launches inside a kernel. 445 mForEachHandler.handleForEachCalls(FD, getTargetAPI()); 446 } 447 } 448 } 449 450 return mGen->HandleTopLevelDecl(D); 451 } 452 453 void Backend::HandleTranslationUnitPre(clang::ASTContext &C) { 454 clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 455 456 if (!mContext->processReducePragmas(this)) 457 return; 458 459 // If we have an invalid RS/FS AST, don't check further. 460 if (!mASTChecker.Validate()) { 461 return; 462 } 463 464 if (mIsFilterscript) { 465 mContext->addPragma("rs_fp_relaxed", ""); 466 } 467 468 int version = mContext->getVersion(); 469 if (version == 0) { 470 // Not setting a version is an error 471 mDiagEngine.Report( 472 mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()), 473 mDiagEngine.getCustomDiagID( 474 clang::DiagnosticsEngine::Error, 475 "missing pragma for version in source file")); 476 } else { 477 slangAssert(version == 1); 478 } 479 480 if (mContext->getReflectJavaPackageName().empty()) { 481 mDiagEngine.Report( 482 mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()), 483 mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error, 484 "missing \"#pragma rs " 485 "java_package_name(com.foo.bar)\" " 486 "in source file")); 487 return; 488 } 489 490 // Create a static global destructor if necessary (to handle RS object 491 // runtime cleanup). 492 clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor(); 493 if (FD) { 494 HandleTopLevelDecl(clang::DeclGroupRef(FD)); 495 } 496 497 // Process any static function declarations 498 for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(), 499 E = TUDecl->decls_end(); I != E; I++) { 500 if ((I->getKind() >= clang::Decl::firstFunction) && 501 (I->getKind() <= clang::Decl::lastFunction)) { 502 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I); 503 if (FD && !FD->isGlobal()) { 504 AnnotateFunction(FD); 505 } 506 } 507 } 508 } 509 510 /////////////////////////////////////////////////////////////////////////////// 511 void Backend::dumpExportVarInfo(llvm::Module *M) { 512 int slotCount = 0; 513 if (mExportVarMetadata == nullptr) 514 mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN); 515 516 llvm::SmallVector<llvm::Metadata *, 2> ExportVarInfo; 517 518 // We emit slot information (#rs_object_slots) for any reference counted 519 // RS type or pointer (which can also be bound). 520 521 for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(), 522 E = mContext->export_vars_end(); 523 I != E; 524 I++) { 525 const RSExportVar *EV = *I; 526 const RSExportType *ET = EV->getType(); 527 bool countsAsRSObject = false; 528 529 // Variable name 530 ExportVarInfo.push_back( 531 llvm::MDString::get(mLLVMContext, EV->getName().c_str())); 532 533 // Type name 534 switch (ET->getClass()) { 535 case RSExportType::ExportClassPrimitive: { 536 const RSExportPrimitiveType *PT = 537 static_cast<const RSExportPrimitiveType*>(ET); 538 ExportVarInfo.push_back( 539 llvm::MDString::get( 540 mLLVMContext, llvm::utostr_32(PT->getType()))); 541 if (PT->isRSObjectType()) { 542 countsAsRSObject = true; 543 } 544 break; 545 } 546 case RSExportType::ExportClassPointer: { 547 ExportVarInfo.push_back( 548 llvm::MDString::get( 549 mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET) 550 ->getPointeeType()->getName()).c_str())); 551 break; 552 } 553 case RSExportType::ExportClassMatrix: { 554 ExportVarInfo.push_back( 555 llvm::MDString::get( 556 mLLVMContext, llvm::utostr_32( 557 /* TODO Strange value. This pushes just a number, quite 558 * different than the other cases. What is this used for? 559 * These are the metadata values that some partner drivers 560 * want to reference (for TBAA, etc.). We may want to look 561 * at whether these provide any reasonable value (or have 562 * distinct enough values to actually depend on). 563 */ 564 DataTypeRSMatrix2x2 + 565 static_cast<const RSExportMatrixType*>(ET)->getDim() - 2))); 566 break; 567 } 568 case RSExportType::ExportClassVector: 569 case RSExportType::ExportClassConstantArray: 570 case RSExportType::ExportClassRecord: { 571 ExportVarInfo.push_back( 572 llvm::MDString::get(mLLVMContext, 573 EV->getType()->getName().c_str())); 574 break; 575 } 576 } 577 578 mExportVarMetadata->addOperand( 579 llvm::MDNode::get(mLLVMContext, ExportVarInfo)); 580 ExportVarInfo.clear(); 581 582 if (mRSObjectSlotsMetadata == nullptr) { 583 mRSObjectSlotsMetadata = 584 M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN); 585 } 586 587 if (countsAsRSObject) { 588 mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext, 589 llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount)))); 590 } 591 592 slotCount++; 593 } 594 } 595 596 void Backend::dumpExportFunctionInfo(llvm::Module *M) { 597 if (mExportFuncMetadata == nullptr) 598 mExportFuncMetadata = 599 M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN); 600 601 llvm::SmallVector<llvm::Metadata *, 1> ExportFuncInfo; 602 603 for (RSContext::const_export_func_iterator 604 I = mContext->export_funcs_begin(), 605 E = mContext->export_funcs_end(); 606 I != E; 607 I++) { 608 const RSExportFunc *EF = *I; 609 610 // Function name 611 if (!EF->hasParam()) { 612 ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext, 613 EF->getName().c_str())); 614 } else { 615 llvm::Function *F = M->getFunction(EF->getName()); 616 llvm::Function *HelperFunction; 617 const std::string HelperFunctionName(".helper_" + EF->getName()); 618 619 slangAssert(F && "Function marked as exported disappeared in Bitcode"); 620 621 // Create helper function 622 { 623 llvm::StructType *HelperFunctionParameterTy = nullptr; 624 std::vector<bool> isStructInput; 625 626 if (!F->getArgumentList().empty()) { 627 std::vector<llvm::Type*> HelperFunctionParameterTys; 628 for (llvm::Function::arg_iterator AI = F->arg_begin(), 629 AE = F->arg_end(); AI != AE; AI++) { 630 if (AI->getType()->isPointerTy() && AI->getType()->getPointerElementType()->isStructTy()) { 631 HelperFunctionParameterTys.push_back(AI->getType()->getPointerElementType()); 632 isStructInput.push_back(true); 633 } else { 634 HelperFunctionParameterTys.push_back(AI->getType()); 635 isStructInput.push_back(false); 636 } 637 } 638 HelperFunctionParameterTy = 639 llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys); 640 } 641 642 if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) { 643 fprintf(stderr, "Failed to export function %s: parameter type " 644 "mismatch during creation of helper function.\n", 645 EF->getName().c_str()); 646 647 const RSExportRecordType *Expected = EF->getParamPacketType(); 648 if (Expected) { 649 fprintf(stderr, "Expected:\n"); 650 Expected->getLLVMType()->dump(); 651 } 652 if (HelperFunctionParameterTy) { 653 fprintf(stderr, "Got:\n"); 654 HelperFunctionParameterTy->dump(); 655 } 656 } 657 658 std::vector<llvm::Type*> Params; 659 if (HelperFunctionParameterTy) { 660 llvm::PointerType *HelperFunctionParameterTyP = 661 llvm::PointerType::getUnqual(HelperFunctionParameterTy); 662 Params.push_back(HelperFunctionParameterTyP); 663 } 664 665 llvm::FunctionType * HelperFunctionType = 666 llvm::FunctionType::get(F->getReturnType(), 667 Params, 668 /* IsVarArgs = */false); 669 670 HelperFunction = 671 llvm::Function::Create(HelperFunctionType, 672 llvm::GlobalValue::ExternalLinkage, 673 HelperFunctionName, 674 M); 675 676 HelperFunction->addFnAttr(llvm::Attribute::NoInline); 677 HelperFunction->setCallingConv(F->getCallingConv()); 678 679 // Create helper function body 680 { 681 llvm::Argument *HelperFunctionParameter = 682 &(*HelperFunction->arg_begin()); 683 llvm::BasicBlock *BB = 684 llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction); 685 llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB); 686 llvm::SmallVector<llvm::Value*, 6> Params; 687 llvm::Value *Idx[2]; 688 689 Idx[0] = 690 llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0); 691 692 // getelementptr and load instruction for all elements in 693 // parameter .p 694 for (size_t i = 0; i < EF->getNumParameters(); i++) { 695 // getelementptr 696 Idx[1] = llvm::ConstantInt::get( 697 llvm::Type::getInt32Ty(mLLVMContext), i); 698 699 llvm::Value *Ptr = NULL; 700 701 Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx); 702 703 // Load is only required for non-struct ptrs 704 if (isStructInput[i]) { 705 Params.push_back(Ptr); 706 } else { 707 llvm::Value *V = IB->CreateLoad(Ptr); 708 Params.push_back(V); 709 } 710 } 711 712 // Call and pass the all elements as parameter to F 713 llvm::CallInst *CI = IB->CreateCall(F, Params); 714 715 CI->setCallingConv(F->getCallingConv()); 716 717 if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext)) { 718 IB->CreateRetVoid(); 719 } else { 720 IB->CreateRet(CI); 721 } 722 723 delete IB; 724 } 725 } 726 727 ExportFuncInfo.push_back( 728 llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str())); 729 } 730 731 mExportFuncMetadata->addOperand( 732 llvm::MDNode::get(mLLVMContext, ExportFuncInfo)); 733 ExportFuncInfo.clear(); 734 } 735 } 736 737 void Backend::dumpExportForEachInfo(llvm::Module *M) { 738 if (mExportForEachNameMetadata == nullptr) { 739 mExportForEachNameMetadata = 740 M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN); 741 } 742 if (mExportForEachSignatureMetadata == nullptr) { 743 mExportForEachSignatureMetadata = 744 M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN); 745 } 746 747 llvm::SmallVector<llvm::Metadata *, 1> ExportForEachName; 748 llvm::SmallVector<llvm::Metadata *, 1> ExportForEachInfo; 749 750 for (RSContext::const_export_foreach_iterator 751 I = mContext->export_foreach_begin(), 752 E = mContext->export_foreach_end(); 753 I != E; 754 I++) { 755 const RSExportForEach *EFE = *I; 756 757 ExportForEachName.push_back( 758 llvm::MDString::get(mLLVMContext, EFE->getName().c_str())); 759 760 mExportForEachNameMetadata->addOperand( 761 llvm::MDNode::get(mLLVMContext, ExportForEachName)); 762 ExportForEachName.clear(); 763 764 ExportForEachInfo.push_back( 765 llvm::MDString::get(mLLVMContext, 766 llvm::utostr_32(EFE->getSignatureMetadata()))); 767 768 mExportForEachSignatureMetadata->addOperand( 769 llvm::MDNode::get(mLLVMContext, ExportForEachInfo)); 770 ExportForEachInfo.clear(); 771 } 772 } 773 774 void Backend::dumpExportReduceInfo(llvm::Module *M) { 775 if (!mExportReduceMetadata) { 776 mExportReduceMetadata = 777 M->getOrInsertNamedMetadata(RS_EXPORT_REDUCE_MN); 778 } 779 780 llvm::SmallVector<llvm::Metadata *, 6> ExportReduceInfo; 781 // Add operand to ExportReduceInfo, padding out missing operands with 782 // nullptr. 783 auto addOperand = [&ExportReduceInfo](uint32_t Idx, llvm::Metadata *N) { 784 while (Idx > ExportReduceInfo.size()) 785 ExportReduceInfo.push_back(nullptr); 786 ExportReduceInfo.push_back(N); 787 }; 788 // Add string operand to ExportReduceInfo, padding out missing operands 789 // with nullptr. 790 // If string is empty, then do not add it unless Always is true. 791 auto addString = [&addOperand, this](uint32_t Idx, const std::string &S, 792 bool Always = true) { 793 if (Always || !S.empty()) 794 addOperand(Idx, llvm::MDString::get(mLLVMContext, S)); 795 }; 796 797 // Add the description of the reduction kernels to the metadata node. 798 for (auto I = mContext->export_reduce_begin(), 799 E = mContext->export_reduce_end(); 800 I != E; ++I) { 801 ExportReduceInfo.clear(); 802 803 int Idx = 0; 804 805 addString(Idx++, (*I)->getNameReduce()); 806 807 addOperand(Idx++, llvm::MDString::get(mLLVMContext, llvm::utostr_32((*I)->getAccumulatorTypeSize()))); 808 809 llvm::SmallVector<llvm::Metadata *, 2> Accumulator; 810 Accumulator.push_back( 811 llvm::MDString::get(mLLVMContext, (*I)->getNameAccumulator())); 812 Accumulator.push_back(llvm::MDString::get( 813 mLLVMContext, 814 llvm::utostr_32((*I)->getAccumulatorSignatureMetadata()))); 815 addOperand(Idx++, llvm::MDTuple::get(mLLVMContext, Accumulator)); 816 817 addString(Idx++, (*I)->getNameInitializer(), false); 818 addString(Idx++, (*I)->getNameCombiner(), false); 819 addString(Idx++, (*I)->getNameOutConverter(), false); 820 addString(Idx++, (*I)->getNameHalter(), false); 821 822 mExportReduceMetadata->addOperand( 823 llvm::MDTuple::get(mLLVMContext, ExportReduceInfo)); 824 } 825 } 826 827 void Backend::dumpExportTypeInfo(llvm::Module *M) { 828 llvm::SmallVector<llvm::Metadata *, 1> ExportTypeInfo; 829 830 for (RSContext::const_export_type_iterator 831 I = mContext->export_types_begin(), 832 E = mContext->export_types_end(); 833 I != E; 834 I++) { 835 // First, dump type name list to export 836 const RSExportType *ET = I->getValue(); 837 838 ExportTypeInfo.clear(); 839 // Type name 840 ExportTypeInfo.push_back( 841 llvm::MDString::get(mLLVMContext, ET->getName().c_str())); 842 843 if (ET->getClass() == RSExportType::ExportClassRecord) { 844 const RSExportRecordType *ERT = 845 static_cast<const RSExportRecordType*>(ET); 846 847 if (mExportTypeMetadata == nullptr) 848 mExportTypeMetadata = 849 M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN); 850 851 mExportTypeMetadata->addOperand( 852 llvm::MDNode::get(mLLVMContext, ExportTypeInfo)); 853 854 // Now, export struct field information to %[struct name] 855 std::string StructInfoMetadataName("%"); 856 StructInfoMetadataName.append(ET->getName()); 857 llvm::NamedMDNode *StructInfoMetadata = 858 M->getOrInsertNamedMetadata(StructInfoMetadataName); 859 llvm::SmallVector<llvm::Metadata *, 3> FieldInfo; 860 861 slangAssert(StructInfoMetadata->getNumOperands() == 0 && 862 "Metadata with same name was created before"); 863 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 864 FE = ERT->fields_end(); 865 FI != FE; 866 FI++) { 867 const RSExportRecordType::Field *F = *FI; 868 869 // 1. field name 870 FieldInfo.push_back(llvm::MDString::get(mLLVMContext, 871 F->getName().c_str())); 872 873 // 2. field type name 874 FieldInfo.push_back( 875 llvm::MDString::get(mLLVMContext, 876 F->getType()->getName().c_str())); 877 878 StructInfoMetadata->addOperand( 879 llvm::MDNode::get(mLLVMContext, FieldInfo)); 880 FieldInfo.clear(); 881 } 882 } // ET->getClass() == RSExportType::ExportClassRecord 883 } 884 } 885 886 void Backend::HandleTranslationUnitPost(llvm::Module *M) { 887 888 if (!mContext->is64Bit()) { 889 M->setDataLayout("e-p:32:32-i64:64-v128:64:128-n32-S64"); 890 } 891 892 if (!mContext->processExports()) 893 return; 894 895 if (mContext->hasExportVar()) 896 dumpExportVarInfo(M); 897 898 if (mContext->hasExportFunc()) 899 dumpExportFunctionInfo(M); 900 901 if (mContext->hasExportForEach()) 902 dumpExportForEachInfo(M); 903 904 if (mContext->hasExportReduce()) 905 dumpExportReduceInfo(M); 906 907 if (mContext->hasExportType()) 908 dumpExportTypeInfo(M); 909 } 910 911 } // namespace slang 912