slang_backend.cpp revision 352e62d65caa48251d9c69cc8b5a82ddfea6b014
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 25e3b677a3041c86a7f860238dd1f5ff9d111b507Stephen Hines * Copyright 2010-2012, The Android Open Source Project 3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License. 6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at 7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software 11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and 14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License. 15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */ 16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_backend.h" 18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <string> 20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <vector> 213a6750f246eed4168351786074691e8eeee5b175David Gross#include <iostream> 22462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 23e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/ASTContext.h" 2465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross#include "clang/AST/Attr.h" 259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/Decl.h" 269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/DeclGroup.h" 273a6750f246eed4168351786074691e8eeee5b175David Gross#include "clang/AST/RecordLayout.h" 28462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/Diagnostic.h" 30e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/TargetInfo.h" 319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/TargetOptions.h" 32462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/CodeGen/ModuleBuilder.h" 34e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 353a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Frontend/CodeGenOptions.h" 369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Frontend/FrontendDiagnostic.h" 37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/ADT/Twine.h" 398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/ADT/StringExtras.h" 40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Bitcode/ReaderWriter.h" 42e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/CodeGen/RegAllocRegistry.h" 44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/CodeGen/SchedulerRegistry.h" 45e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Constant.h" 478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Constants.h" 488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DataLayout.h" 498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DebugLoc.h" 508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DerivedTypes.h" 518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Function.h" 528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/IRBuilder.h" 538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/IRPrintingPasses.h" 5423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/LLVMContext.h" 5523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Metadata.h" 568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Module.h" 57e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 589207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Transforms/IPO/PassManagerBuilder.h" 59fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao 60e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Target/TargetMachine.h" 61e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Target/TargetOptions.h" 629207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Support/TargetRegistry.h" 6377703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao 6477703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao#include "llvm/MC/SubtargetFeature.h" 65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 666e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang.h" 68dabd246c169fe8bc7d80a31779311bfc583b2ea0Matt Wala#include "slang_bitcode_gen.h" 698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_context.h" 708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_foreach.h" 718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_func.h" 72c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#include "slang_rs_export_reduce.h" 738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_type.h" 748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_var.h" 758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_metadata.h" 768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 772770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross#include "rs_cc_options.h" 782770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross 79552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines#include "strip_unknown_attributes.h" 806315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 81e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 82462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 833a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Backend::CreateFunctionPasses() { 843a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang if (!mPerFunctionPasses) { 85c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines mPerFunctionPasses = new llvm::legacy::FunctionPassManager(mpModule); 863a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 87fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao llvm::PassManagerBuilder PMBuilder; 88fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel; 89fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao PMBuilder.populateFunctionPassManager(*mPerFunctionPasses); 903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang } 913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Backend::CreateModulePasses() { 943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang if (!mPerModulePasses) { 95c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines mPerModulePasses = new llvm::legacy::PassManager(); 963a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 97fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao llvm::PassManagerBuilder PMBuilder; 98fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel; 99fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize; 100b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar PMBuilder.DisableUnitAtATime = 0; // TODO Pirama confirm if this is right 101fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao 102fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao if (mCodeGenOpts.UnrollLoops) { 103fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao PMBuilder.DisableUnrollLoops = 0; 104fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao } else { 105fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao PMBuilder.DisableUnrollLoops = 1; 106fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao } 107fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao 108fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao PMBuilder.populateModulePassManager(*mPerModulePasses); 109552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines // Add a pass to strip off unknown/unsupported attributes. 110552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines mPerModulePasses->add(createStripUnknownAttributesPass()); 1113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang } 1123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 1133a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 114462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Backend::CreateCodeGenPasses() { 1153a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object)) 1169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 117462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Now we add passes for code emitting 1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mCodeGenPasses) { 120462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return true; 1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 122c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines mCodeGenPasses = new llvm::legacy::FunctionPassManager(mpModule); 1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Create the TargetMachine for generating code. 1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::string Triple = mpModule->getTargetTriple(); 1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::string Error; 1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::Target* TargetInfo = 1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::TargetRegistry::lookupTarget(Triple, Error); 1315abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (TargetInfo == nullptr) { 1329207a2e495c8363606861e4f034504ec5c153dabLogan Chien mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error; 1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 136ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien // Target Machine Options 137ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien llvm::TargetOptions Options; 138ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien 139167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar // Use soft-float ABI for ARM (which is the target used by Slang during code 140167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar // generation). Codegen still uses hardware FPU by default. To use software 141167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar // floating point, add 'soft-float' feature to FeaturesStr below. 142167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar Options.FloatABIType = llvm::FloatABI::Soft; 1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // BCC needs all unknown symbols resolved at compilation time. So we don't 1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // need any relocation model. 146ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien llvm::Reloc::Model RM = llvm::Reloc::Static; 1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14841ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang // This is set for the linker (specify how large of the virtual addresses we 14941ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang // can access for all unknown symbols.) 1509207a2e495c8363606861e4f034504ec5c153dabLogan Chien llvm::CodeModel::Model CM; 1510b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines if (mpModule->getDataLayout().getPointerSize() == 4) { 1529207a2e495c8363606861e4f034504ec5c153dabLogan Chien CM = llvm::CodeModel::Small; 1539207a2e495c8363606861e4f034504ec5c153dabLogan Chien } else { 15441ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang // The target may have pointer size greater than 32 (e.g. x86_64 15541ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang // architecture) may need large data address model 1569207a2e495c8363606861e4f034504ec5c153dabLogan Chien CM = llvm::CodeModel::Medium; 1579207a2e495c8363606861e4f034504ec5c153dabLogan Chien } 1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Setup feature string 1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::string FeaturesStr; 1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) { 1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::SubtargetFeatures Features; 1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (std::vector<std::string>::const_iterator 1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end(); 1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I != E; 1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I++) 1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Features.AddFeature(*I); 1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FeaturesStr = Features.getString(); 1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1729207a2e495c8363606861e4f034504ec5c153dabLogan Chien 1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::TargetMachine *TM = 1749207a2e495c8363606861e4f034504ec5c153dabLogan Chien TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr, 175ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien Options, RM, CM); 1769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Register allocation policy: 1789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // createFastRegisterAllocator: fast but bad quality 1792c6bad5038d8509466b9e0f9aa6a8ae533c0e029Logan Chien // createGreedyRegisterAllocator: not so fast but good quality 1809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ? 1819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::createFastRegisterAllocator : 1822c6bad5038d8509466b9e0f9aa6a8ae533c0e029Logan Chien llvm::createGreedyRegisterAllocator); 1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default; 18577703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao if (mCodeGenOpts.OptimizationLevel == 0) { 1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao OptLevel = llvm::CodeGenOpt::None; 18777703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao } else if (mCodeGenOpts.OptimizationLevel == 3) { 1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao OptLevel = llvm::CodeGenOpt::Aggressive; 18977703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao } 1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::TargetMachine::CodeGenFileType CGFT = 1926315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr llvm::TargetMachine::CGFT_AssemblyFile; 19377703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao if (mOT == Slang::OT_Object) { 1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao CGFT = llvm::TargetMachine::CGFT_ObjectFile; 19577703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao } 19621cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar if (TM->addPassesToEmitFile(*mCodeGenPasses, mBufferOutStream, 1979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao CGFT, OptLevel)) { 1989207a2e495c8363606861e4f034504ec5c153dabLogan Chien mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target); 1999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 203462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 204462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc BrouilletBackend::Backend(RSContext *Context, clang::DiagnosticsEngine *DiagEngine, 2068f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar const RSCCOptions &Opts, 2078f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar const clang::HeaderSearchOptions &HeaderSearchOpts, 2088f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar const clang::PreprocessorOptions &PreprocessorOpts, 2098f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar const clang::CodeGenOptions &CodeGenOpts, 2108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet const clang::TargetOptions &TargetOpts, PragmaList *Pragmas, 2118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::raw_ostream *OS, Slang::OutputType OT, 2128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet clang::SourceManager &SourceMgr, bool AllowRSPrefix, 2138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet bool IsFilterscript) 2148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet : ASTConsumer(), mTargetOpts(TargetOpts), mpModule(nullptr), mpOS(OS), 2158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mOT(OT), mGen(nullptr), mPerFunctionPasses(nullptr), 21621cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar mPerModulePasses(nullptr), mCodeGenPasses(nullptr), 21721cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar mBufferOutStream(*mpOS), mContext(Context), 2182770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross mSourceMgr(SourceMgr), mASTPrint(Opts.mASTPrint), mAllowRSPrefix(AllowRSPrefix), 2198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mIsFilterscript(IsFilterscript), mExportVarMetadata(nullptr), 2208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mExportFuncMetadata(nullptr), mExportForEachNameMetadata(nullptr), 221dbf5b61ea24012f883e238fd17bdca0758f181d6David Gross mExportForEachSignatureMetadata(nullptr), 2228ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross mExportReduceMetadata(nullptr), 223c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala mExportTypeMetadata(nullptr), mRSObjectSlotsMetadata(nullptr), 224c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala mRefCount(mContext->getASTContext()), 2258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mASTChecker(Context, Context->getTargetAPI(), IsFilterscript), 226fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni mForEachHandler(Context), 227b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar mLLVMContext(slang::getGlobalLLVMContext()), mDiagEngine(*DiagEngine), 2288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mCodeGenOpts(CodeGenOpts), mPragmas(Pragmas) { 2298f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar mGen = CreateLLVMCodeGen(mDiagEngine, "", HeaderSearchOpts, PreprocessorOpts, 2308f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar mCodeGenOpts, mLLVMContext); 231462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 232462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::Initialize(clang::ASTContext &Ctx) { 2349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mGen->Initialize(Ctx); 235462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mpModule = mGen->GetModule(); 237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 238462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::HandleTranslationUnit(clang::ASTContext &Ctx) { 24068fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang HandleTranslationUnitPre(Ctx); 24168fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang 2422770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross if (mASTPrint) 2432770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross Ctx.getTranslationUnitDecl()->dump(); 2442770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross 2459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mGen->HandleTranslationUnit(Ctx); 246462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Here, we complete a translation unit (whole translation unit is now in LLVM 2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // IR). Now, interact with LLVM backend to generate actual machine code (asm 2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // or machine code, whatever.) 250462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Silently ignore if we weren't initialized for some reason. 25241ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang if (!mpModule) 2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 254462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::Module *M = mGen->ReleaseModule(); 2569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!M) { 2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // The module has been released by IR gen on failures, do not double free. 2585abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes mpModule = nullptr; 2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2626e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(mpModule == M && 2636e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Unexpected module change during LLVM IR generation"); 2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Insert #pragma information into metadata section of module 2663fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines if (!mPragmas->empty()) { 2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::NamedMDNode *PragmaMetadata = 2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName); 2693fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end(); 2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I != E; 2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I++) { 272c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines llvm::SmallVector<llvm::Metadata*, 2> Pragma; 2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Name goes first 2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first)); 2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // And then value 2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second)); 27783f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Create MDNode and insert into PragmaMetadata 2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PragmaMetadata->addOperand( 28018c8829f2bd3cbe0d02471588c6643c0a8c6ca3cStephen Hines llvm::MDNode::get(mLLVMContext, Pragma)); 281462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 283462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 28468fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang HandleTranslationUnitPost(mpModule); 285462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Create passes for optimization and code emission 287462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Create and run per-function passes 2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao CreateFunctionPasses(); 2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mPerFunctionPasses) { 2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mPerFunctionPasses->doInitialization(); 292462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end(); 2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I != E; 2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I++) 2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!I->isDeclaration()) 2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mPerFunctionPasses->run(*I); 298462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mPerFunctionPasses->doFinalization(); 3009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 301462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Create and run module passes 3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao CreateModulePasses(); 3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mPerModulePasses) 3059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mPerModulePasses->run(*mpModule); 3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3073a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang switch (mOT) { 3083a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case Slang::OT_Assembly: 3093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case Slang::OT_Object: { 3106315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr if (!CreateCodeGenPasses()) 3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mCodeGenPasses->doInitialization(); 314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end(); 3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I != E; 3179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I++) 3186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr if (!I->isDeclaration()) 3199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mCodeGenPasses->run(*I); 3209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mCodeGenPasses->doFinalization(); 3229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 3239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3243a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case Slang::OT_LLVMAssembly: { 325c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines llvm::legacy::PassManager *LLEmitPM = new llvm::legacy::PassManager(); 32621cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar LLEmitPM->add(llvm::createPrintModulePass(mBufferOutStream)); 3279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LLEmitPM->run(*mpModule); 3289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 329462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 3303a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case Slang::OT_Bitcode: { 331dabd246c169fe8bc7d80a31779311bfc583b2ea0Matt Wala writeBitcode(mBufferOutStream, *mpModule, getTargetAPI(), 332b130e157d3a5c2256e7aa0005d7134f3ac060c56Stephen McGroarty mCodeGenOpts.OptimizationLevel, mCodeGenOpts.getDebugInfo()); 3339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 3349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3353a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case Slang::OT_Nothing: { 3369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 3379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 3396e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown output type"); 3409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 342462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 343462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3443a6750f246eed4168351786074691e8eeee5b175David Gross// Insert explicit padding fields into struct to follow the current layout. 3453a6750f246eed4168351786074691e8eeee5b175David Gross// 3463a6750f246eed4168351786074691e8eeee5b175David Gross// A similar algorithm is present in PadHelperFunctionStruct(). 3473a6750f246eed4168351786074691e8eeee5b175David Grossvoid Backend::PadStruct(clang::RecordDecl* RD) { 3483a6750f246eed4168351786074691e8eeee5b175David Gross // Example of padding: 3493a6750f246eed4168351786074691e8eeee5b175David Gross // 3503a6750f246eed4168351786074691e8eeee5b175David Gross // // ORIGINAL CODE // TRANSFORMED CODE 3513a6750f246eed4168351786074691e8eeee5b175David Gross // struct foo { struct foo { 3523a6750f246eed4168351786074691e8eeee5b175David Gross // int a; int a; 3533a6750f246eed4168351786074691e8eeee5b175David Gross // // 4 bytes of padding char <RS_PADDING_FIELD_NAME>[4]; 3543a6750f246eed4168351786074691e8eeee5b175David Gross // long b; long b; 3553a6750f246eed4168351786074691e8eeee5b175David Gross // int c; int c; 3563a6750f246eed4168351786074691e8eeee5b175David Gross // // 4 bytes of (tail) padding char <RS_PADDING_FIELD_NAME>[4]; 3573a6750f246eed4168351786074691e8eeee5b175David Gross // }; }; 3583a6750f246eed4168351786074691e8eeee5b175David Gross 3593a6750f246eed4168351786074691e8eeee5b175David Gross // We collect all of RD's fields in a vector FieldsInfo. We 3603a6750f246eed4168351786074691e8eeee5b175David Gross // represent tail padding as an entry in the FieldsInfo vector with a 3613a6750f246eed4168351786074691e8eeee5b175David Gross // null FieldDecl. 3623a6750f246eed4168351786074691e8eeee5b175David Gross typedef std::pair<size_t, clang::FieldDecl*> FieldInfoType; // (pre-field padding bytes, field) 3633a6750f246eed4168351786074691e8eeee5b175David Gross std::vector<FieldInfoType> FieldsInfo; 3643a6750f246eed4168351786074691e8eeee5b175David Gross 3653a6750f246eed4168351786074691e8eeee5b175David Gross // RenderScript is C99-based, so we only expect to see fields. We 3663a6750f246eed4168351786074691e8eeee5b175David Gross // could iterate over fields, but instead let's iterate over 3673a6750f246eed4168351786074691e8eeee5b175David Gross // everything, to verify that there are only fields. 3683a6750f246eed4168351786074691e8eeee5b175David Gross for (clang::Decl* D : RD->decls()) { 3693a6750f246eed4168351786074691e8eeee5b175David Gross clang::FieldDecl* FD = clang::dyn_cast<clang::FieldDecl>(D); 3703a6750f246eed4168351786074691e8eeee5b175David Gross slangAssert(FD && "found a non field declaration within a struct"); 3713a6750f246eed4168351786074691e8eeee5b175David Gross FieldsInfo.push_back(std::make_pair(size_t(0), FD)); 3723a6750f246eed4168351786074691e8eeee5b175David Gross } 3733a6750f246eed4168351786074691e8eeee5b175David Gross 3743a6750f246eed4168351786074691e8eeee5b175David Gross clang::ASTContext& ASTC = mContext->getASTContext(); 3753a6750f246eed4168351786074691e8eeee5b175David Gross 3763a6750f246eed4168351786074691e8eeee5b175David Gross // ASTContext caches record layout. We may transform the record in a way 3773a6750f246eed4168351786074691e8eeee5b175David Gross // that would render this cached information incorrect. clang does 3783a6750f246eed4168351786074691e8eeee5b175David Gross // not provide any way to invalidate this cached information. We 3793a6750f246eed4168351786074691e8eeee5b175David Gross // take the following approach: 3803a6750f246eed4168351786074691e8eeee5b175David Gross // 3813a6750f246eed4168351786074691e8eeee5b175David Gross // 1. ASSUME that record layout has not yet been computed for RD. 3823a6750f246eed4168351786074691e8eeee5b175David Gross // 3833a6750f246eed4168351786074691e8eeee5b175David Gross // 2. Create a temporary clone of RD, and compute its layout. 3843a6750f246eed4168351786074691e8eeee5b175David Gross // ASSUME that we know how to clone RD in a way that copies all the 3853a6750f246eed4168351786074691e8eeee5b175David Gross // properties that are relevant to its layout. 3863a6750f246eed4168351786074691e8eeee5b175David Gross // 3873a6750f246eed4168351786074691e8eeee5b175David Gross // 3. Use the layout information from the temporary clone to 3883a6750f246eed4168351786074691e8eeee5b175David Gross // transform RD. 3893a6750f246eed4168351786074691e8eeee5b175David Gross // 3903a6750f246eed4168351786074691e8eeee5b175David Gross // NOTE: ASTContext also caches TypeInfo (see 3913a6750f246eed4168351786074691e8eeee5b175David Gross // ASTContext::getTypeInfo()). ASSUME that inserting padding 3923a6750f246eed4168351786074691e8eeee5b175David Gross // fields doesn't change the type in any way that affects 3933a6750f246eed4168351786074691e8eeee5b175David Gross // TypeInfo. 3943a6750f246eed4168351786074691e8eeee5b175David Gross // 3953a6750f246eed4168351786074691e8eeee5b175David Gross // NOTE: A RecordType knows its associated RecordDecl -- so even 3963a6750f246eed4168351786074691e8eeee5b175David Gross // while we're manipulating RD, the associated RecordType 3973a6750f246eed4168351786074691e8eeee5b175David Gross // still recognizes RD as its RecordDecl. ASSUME that we 3983a6750f246eed4168351786074691e8eeee5b175David Gross // don't do anything during our manipulation that would cause 3993a6750f246eed4168351786074691e8eeee5b175David Gross // the RecordType to be followed to RD while RD is in a 4003a6750f246eed4168351786074691e8eeee5b175David Gross // partially transformed state. 4013a6750f246eed4168351786074691e8eeee5b175David Gross 4023a6750f246eed4168351786074691e8eeee5b175David Gross // The assumptions above may be brittle, and if they are incorrect, 4033a6750f246eed4168351786074691e8eeee5b175David Gross // we may get mysterious failures. 4043a6750f246eed4168351786074691e8eeee5b175David Gross 4053a6750f246eed4168351786074691e8eeee5b175David Gross // create a temporary clone 4063a6750f246eed4168351786074691e8eeee5b175David Gross clang::RecordDecl* RDForLayout = 4073a6750f246eed4168351786074691e8eeee5b175David Gross clang::RecordDecl::Create(ASTC, clang::TTK_Struct, RD->getDeclContext(), 4083a6750f246eed4168351786074691e8eeee5b175David Gross clang::SourceLocation(), clang::SourceLocation(), 4093a6750f246eed4168351786074691e8eeee5b175David Gross nullptr /* IdentifierInfo */); 4103a6750f246eed4168351786074691e8eeee5b175David Gross RDForLayout->startDefinition(); 4113a6750f246eed4168351786074691e8eeee5b175David Gross RDForLayout->setTypeForDecl(RD->getTypeForDecl()); 412352e62d65caa48251d9c69cc8b5a82ddfea6b014I-Jui (Ray) Sung if (RD->hasAttrs()) 413352e62d65caa48251d9c69cc8b5a82ddfea6b014I-Jui (Ray) Sung RDForLayout->setAttrs(RD->getAttrs()); 4143a6750f246eed4168351786074691e8eeee5b175David Gross RDForLayout->completeDefinition(); 4153a6750f246eed4168351786074691e8eeee5b175David Gross 4163a6750f246eed4168351786074691e8eeee5b175David Gross // move all fields from RD to RDForLayout 4173a6750f246eed4168351786074691e8eeee5b175David Gross for (const auto &info : FieldsInfo) { 4183a6750f246eed4168351786074691e8eeee5b175David Gross RD->removeDecl(info.second); 419352e62d65caa48251d9c69cc8b5a82ddfea6b014I-Jui (Ray) Sung info.second->setLexicalDeclContext(RDForLayout); 4203a6750f246eed4168351786074691e8eeee5b175David Gross RDForLayout->addDecl(info.second); 4213a6750f246eed4168351786074691e8eeee5b175David Gross } 4223a6750f246eed4168351786074691e8eeee5b175David Gross 4233a6750f246eed4168351786074691e8eeee5b175David Gross const clang::ASTRecordLayout& RL = ASTC.getASTRecordLayout(RDForLayout); 4243a6750f246eed4168351786074691e8eeee5b175David Gross 4253a6750f246eed4168351786074691e8eeee5b175David Gross // An exportable type cannot contain a bitfield. However, it's 4263a6750f246eed4168351786074691e8eeee5b175David Gross // possible that this current type might have a bitfield and yet 4273a6750f246eed4168351786074691e8eeee5b175David Gross // share a common initial sequence with an exportable type, so even 4283a6750f246eed4168351786074691e8eeee5b175David Gross // if the current type has a bitfield, the current type still 4293a6750f246eed4168351786074691e8eeee5b175David Gross // needs to have explicit padding inserted (in case the two types 4303a6750f246eed4168351786074691e8eeee5b175David Gross // under discussion are members of a union). We don't need to 4313a6750f246eed4168351786074691e8eeee5b175David Gross // insert any padding after the bitfield, however, because that 4323a6750f246eed4168351786074691e8eeee5b175David Gross // would be beyond the common initial sequence. 4333a6750f246eed4168351786074691e8eeee5b175David Gross bool foundBitField = false; 4343a6750f246eed4168351786074691e8eeee5b175David Gross 4353a6750f246eed4168351786074691e8eeee5b175David Gross // Is there any padding in this struct? 4363a6750f246eed4168351786074691e8eeee5b175David Gross bool foundPadding = false; 4373a6750f246eed4168351786074691e8eeee5b175David Gross 4383a6750f246eed4168351786074691e8eeee5b175David Gross unsigned fieldNo = 0; 4393a6750f246eed4168351786074691e8eeee5b175David Gross uint64_t fieldPrePaddingOffset = 0; // byte offset of pre-field padding within struct 4403a6750f246eed4168351786074691e8eeee5b175David Gross for (auto &info : FieldsInfo) { 4413a6750f246eed4168351786074691e8eeee5b175David Gross const clang::FieldDecl* FD = info.second; 4423a6750f246eed4168351786074691e8eeee5b175David Gross 4433a6750f246eed4168351786074691e8eeee5b175David Gross if ((foundBitField = FD->isBitField())) 4443a6750f246eed4168351786074691e8eeee5b175David Gross break; 4453a6750f246eed4168351786074691e8eeee5b175David Gross 4463a6750f246eed4168351786074691e8eeee5b175David Gross const uint64_t fieldOffset = RL.getFieldOffset(fieldNo) >> 3; 4473a6750f246eed4168351786074691e8eeee5b175David Gross const size_t prePadding = fieldOffset - fieldPrePaddingOffset; 4483a6750f246eed4168351786074691e8eeee5b175David Gross foundPadding |= (prePadding != 0); 4493a6750f246eed4168351786074691e8eeee5b175David Gross info.first = prePadding; 4503a6750f246eed4168351786074691e8eeee5b175David Gross 4513a6750f246eed4168351786074691e8eeee5b175David Gross // get ready for the next field 4523a6750f246eed4168351786074691e8eeee5b175David Gross // 4533a6750f246eed4168351786074691e8eeee5b175David Gross // assumes that getTypeSize() is the storage size of the Type -- for example, 4543a6750f246eed4168351786074691e8eeee5b175David Gross // that it includes a struct's tail padding (if any) 4553a6750f246eed4168351786074691e8eeee5b175David Gross // 4563a6750f246eed4168351786074691e8eeee5b175David Gross fieldPrePaddingOffset = fieldOffset + (ASTC.getTypeSize(FD->getType()) >> 3); 4573a6750f246eed4168351786074691e8eeee5b175David Gross ++fieldNo; 4583a6750f246eed4168351786074691e8eeee5b175David Gross } 4593a6750f246eed4168351786074691e8eeee5b175David Gross 4603a6750f246eed4168351786074691e8eeee5b175David Gross if (!foundBitField) { 4613a6750f246eed4168351786074691e8eeee5b175David Gross // In order to ensure that the front end (including reflected 4623a6750f246eed4168351786074691e8eeee5b175David Gross // code) and back end agree on struct size (not just field 4633a6750f246eed4168351786074691e8eeee5b175David Gross // offsets) we may need to add explicit tail padding, just as we'e 4643a6750f246eed4168351786074691e8eeee5b175David Gross // added explicit padding between fields. 4653a6750f246eed4168351786074691e8eeee5b175David Gross slangAssert(RL.getSize().getQuantity() >= fieldPrePaddingOffset); 4663a6750f246eed4168351786074691e8eeee5b175David Gross if (const size_t tailPadding = RL.getSize().getQuantity() - fieldPrePaddingOffset) { 4673a6750f246eed4168351786074691e8eeee5b175David Gross foundPadding = true; 4683a6750f246eed4168351786074691e8eeee5b175David Gross FieldsInfo.push_back(std::make_pair(tailPadding, nullptr)); 4693a6750f246eed4168351786074691e8eeee5b175David Gross } 4703a6750f246eed4168351786074691e8eeee5b175David Gross } 4713a6750f246eed4168351786074691e8eeee5b175David Gross 4723a6750f246eed4168351786074691e8eeee5b175David Gross if (false /* change to "true" for extra debugging output */) { 4733a6750f246eed4168351786074691e8eeee5b175David Gross if (foundPadding) { 4743a6750f246eed4168351786074691e8eeee5b175David Gross std::cout << "PadStruct(" << RD->getNameAsString() << "):" << std::endl; 4753a6750f246eed4168351786074691e8eeee5b175David Gross for (const auto &info : FieldsInfo) 4763a6750f246eed4168351786074691e8eeee5b175David Gross std::cout << " " << info.first << ", " << (info.second ? info.second->getNameAsString() : "<tail>") << std::endl; 4773a6750f246eed4168351786074691e8eeee5b175David Gross } 4783a6750f246eed4168351786074691e8eeee5b175David Gross } 4793a6750f246eed4168351786074691e8eeee5b175David Gross 4803a6750f246eed4168351786074691e8eeee5b175David Gross if (foundPadding && Slang::IsLocInRSHeaderFile(RD->getLocation(), mSourceMgr)) { 4813a6750f246eed4168351786074691e8eeee5b175David Gross mContext->ReportError(RD->getLocation(), "system structure contains padding: '%0'") 4823a6750f246eed4168351786074691e8eeee5b175David Gross << RD->getName(); 4833a6750f246eed4168351786074691e8eeee5b175David Gross } 4843a6750f246eed4168351786074691e8eeee5b175David Gross 4853a6750f246eed4168351786074691e8eeee5b175David Gross // now move fields from RDForLayout to RD, and add any necessary 4863a6750f246eed4168351786074691e8eeee5b175David Gross // padding fields 4873a6750f246eed4168351786074691e8eeee5b175David Gross const clang::QualType byteType = ASTC.getIntTypeForBitwidth(8, false /* not signed */); 4883a6750f246eed4168351786074691e8eeee5b175David Gross clang::IdentifierInfo* const paddingIdentifierInfo = &ASTC.Idents.get(RS_PADDING_FIELD_NAME); 4893a6750f246eed4168351786074691e8eeee5b175David Gross for (const auto &info : FieldsInfo) { 4903a6750f246eed4168351786074691e8eeee5b175David Gross if (info.first != 0) { 4913a6750f246eed4168351786074691e8eeee5b175David Gross // Create a padding field: "char <RS_PADDING_FIELD_NAME>[<info.first>];" 4923a6750f246eed4168351786074691e8eeee5b175David Gross 4933a6750f246eed4168351786074691e8eeee5b175David Gross // TODO: Do we need to do anything else to keep this field from being shown in debugger? 4943a6750f246eed4168351786074691e8eeee5b175David Gross // There's no source location, and the field is marked as implicit. 4953a6750f246eed4168351786074691e8eeee5b175David Gross const clang::QualType paddingType = 4963a6750f246eed4168351786074691e8eeee5b175David Gross ASTC.getConstantArrayType(byteType, 4973a6750f246eed4168351786074691e8eeee5b175David Gross llvm::APInt(sizeof(info.first) << 3, info.first), 4983a6750f246eed4168351786074691e8eeee5b175David Gross clang::ArrayType::Normal, 0 /* IndexTypeQuals */); 4993a6750f246eed4168351786074691e8eeee5b175David Gross clang::FieldDecl* const FD = 5003a6750f246eed4168351786074691e8eeee5b175David Gross clang::FieldDecl::Create(ASTC, RD, clang::SourceLocation(), clang::SourceLocation(), 5013a6750f246eed4168351786074691e8eeee5b175David Gross paddingIdentifierInfo, 5023a6750f246eed4168351786074691e8eeee5b175David Gross paddingType, 5033a6750f246eed4168351786074691e8eeee5b175David Gross nullptr, // TypeSourceInfo* 5043a6750f246eed4168351786074691e8eeee5b175David Gross nullptr, // BW (bitwidth) 5053a6750f246eed4168351786074691e8eeee5b175David Gross false, // Mutable = false 5063a6750f246eed4168351786074691e8eeee5b175David Gross clang::ICIS_NoInit); 5073a6750f246eed4168351786074691e8eeee5b175David Gross FD->setImplicit(true); 5083a6750f246eed4168351786074691e8eeee5b175David Gross RD->addDecl(FD); 5093a6750f246eed4168351786074691e8eeee5b175David Gross } 5103a6750f246eed4168351786074691e8eeee5b175David Gross if (info.second != nullptr) { 5113a6750f246eed4168351786074691e8eeee5b175David Gross RDForLayout->removeDecl(info.second); 512352e62d65caa48251d9c69cc8b5a82ddfea6b014I-Jui (Ray) Sung info.second->setLexicalDeclContext(RD); 5133a6750f246eed4168351786074691e8eeee5b175David Gross RD->addDecl(info.second); 5143a6750f246eed4168351786074691e8eeee5b175David Gross } 5153a6750f246eed4168351786074691e8eeee5b175David Gross } 5163a6750f246eed4168351786074691e8eeee5b175David Gross 5173a6750f246eed4168351786074691e8eeee5b175David Gross // There does not appear to be any safe way to delete a RecordDecl 5183a6750f246eed4168351786074691e8eeee5b175David Gross // -- for example, there is no RecordDecl destructor to invalidate 5193a6750f246eed4168351786074691e8eeee5b175David Gross // cached record layout, and if we were to get unlucky, some future 5203a6750f246eed4168351786074691e8eeee5b175David Gross // RecordDecl could be allocated in the same place as a deleted 5213a6750f246eed4168351786074691e8eeee5b175David Gross // RDForLayout and "inherit" the cached record layout from 5223a6750f246eed4168351786074691e8eeee5b175David Gross // RDForLayout. 5233a6750f246eed4168351786074691e8eeee5b175David Gross} 5243a6750f246eed4168351786074691e8eeee5b175David Gross 5259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::HandleTagDeclDefinition(clang::TagDecl *D) { 5263a6750f246eed4168351786074691e8eeee5b175David Gross // we want to insert explicit padding fields into structs per http://b/29154200 and http://b/28070272 5273a6750f246eed4168351786074691e8eeee5b175David Gross switch (D->getTagKind()) { 5283a6750f246eed4168351786074691e8eeee5b175David Gross case clang::TTK_Struct: 5293a6750f246eed4168351786074691e8eeee5b175David Gross PadStruct(llvm::cast<clang::RecordDecl>(D)); 5303a6750f246eed4168351786074691e8eeee5b175David Gross break; 5313a6750f246eed4168351786074691e8eeee5b175David Gross 5323a6750f246eed4168351786074691e8eeee5b175David Gross case clang::TTK_Union: 5333a6750f246eed4168351786074691e8eeee5b175David Gross // cannot be part of an exported type 5343a6750f246eed4168351786074691e8eeee5b175David Gross break; 5353a6750f246eed4168351786074691e8eeee5b175David Gross 5363a6750f246eed4168351786074691e8eeee5b175David Gross case clang::TTK_Enum: 5373a6750f246eed4168351786074691e8eeee5b175David Gross // a scalar 5383a6750f246eed4168351786074691e8eeee5b175David Gross break; 5393a6750f246eed4168351786074691e8eeee5b175David Gross 5403a6750f246eed4168351786074691e8eeee5b175David Gross case clang::TTK_Class: 5413a6750f246eed4168351786074691e8eeee5b175David Gross case clang::TTK_Interface: 5423a6750f246eed4168351786074691e8eeee5b175David Gross default: 5433a6750f246eed4168351786074691e8eeee5b175David Gross slangAssert(false && "Unexpected TagTypeKind"); 5443a6750f246eed4168351786074691e8eeee5b175David Gross break; 5453a6750f246eed4168351786074691e8eeee5b175David Gross } 5469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mGen->HandleTagDeclDefinition(D); 547462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 548462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::CompleteTentativeDefinition(clang::VarDecl *D) { 5509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mGen->CompleteTentativeDefinition(D); 551462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 552462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 553462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoBackend::~Backend() { 5549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete mpModule; 5559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete mGen; 5569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete mPerFunctionPasses; 5579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete mPerModulePasses; 5589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete mCodeGenPasses; 559462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 560e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 5618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet// 1) Add zero initialization of local RS object types 5628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::AnnotateFunction(clang::FunctionDecl *FD) { 5638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (FD && 5648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet FD->hasBody() && 565c8f5b2dad5c4ad2294d180b562d486342f29fb55I-Jui (Ray) Sung !FD->isImplicit() && 5668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) { 5678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mRefCount.Init(); 568283a6cf32b808c703b219862ac491df3c9fc8b4bYang Ni mRefCount.SetDeclContext(FD); 5698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mRefCount.Visit(FD->getBody()); 5708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 5718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet} 5728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 5738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) { 5742615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni // Find and remember the types for rs_allocation and rs_script_call_t so 5752615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni // they can be used later for translating rsForEach() calls. 5762615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); 5772615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni (mContext->getAllocationType().isNull() || 5782615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni mContext->getScriptCallType().isNull()) && 5792615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni I != E; I++) { 5802615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni if (clang::TypeDecl* TD = llvm::dyn_cast<clang::TypeDecl>(*I)) { 5812615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni clang::StringRef TypeName = TD->getName(); 5822615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni if (TypeName.equals("rs_allocation")) { 58388f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni mContext->setAllocationType(TD); 5842615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni } else if (TypeName.equals("rs_script_call_t")) { 5852615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni mContext->setScriptCallType(TD); 58688f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni } 58788f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni } 58888f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni } 58988f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni 5908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Disallow user-defined functions with prefix "rs" 5918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (!mAllowRSPrefix) { 5928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Iterate all function declarations in the program. 5938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); 5948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet I != E; I++) { 5958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I); 5968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (FD == nullptr) 5978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet continue; 5988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (!FD->getName().startswith("rs")) // Check prefix 5998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet continue; 6008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) 6018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mContext->ReportError(FD->getLocation(), 6028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet "invalid function name prefix, " 6038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet "\"rs\" is reserved: '%0'") 6048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet << FD->getName(); 6058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 6068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 6078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 6088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) { 6098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I); 61065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (FD) { 6115e306b944425a952fe744f59d828538137a59375David Gross // Handle forward reference from pragma (see 6125e306b944425a952fe744f59d828538137a59375David Gross // RSReducePragmaHandler::HandlePragma for backward reference). 6135e306b944425a952fe744f59d828538137a59375David Gross mContext->markUsedByReducePragma(FD, RSContext::CheckNameYes); 61465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (FD->isGlobal()) { 61565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross // Check that we don't have any array parameters being misinterpreted as 61665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross // kernel pointers due to the C type system's array to pointer decay. 61765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross size_t numParams = FD->getNumParams(); 61865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross for (size_t i = 0; i < numParams; i++) { 61965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross const clang::ParmVarDecl *PVD = FD->getParamDecl(i); 62065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross clang::QualType QT = PVD->getOriginalType(); 62165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (QT->isArrayType()) { 62265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross mContext->ReportError( 62365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross PVD->getTypeSpecStartLoc(), 62465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross "exported function parameters may not have array type: %0") 62565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross << QT; 62665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross } 6278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 62865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross AnnotateFunction(FD); 6298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 6308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 631fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni 63240bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni if (getTargetAPI() >= SLANG_FEATURE_SINGLE_SOURCE_API) { 633c8f5b2dad5c4ad2294d180b562d486342f29fb55I-Jui (Ray) Sung if (FD && FD->hasBody() && !FD->isImplicit() && 6349319dfc974a82794d46e9f474f316590f480b976Yang Ni !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) { 635b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar if (FD->hasAttr<clang::RenderScriptKernelAttr>()) { 63640bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni // Log functions with attribute "kernel" by their names, and assign 63740bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni // them slot numbers. Any other function cannot be used in a 63840bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni // rsForEach() or rsForEachWithOptions() call, including old-style 63940bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni // kernel functions which are defined without the "kernel" attribute. 6409319dfc974a82794d46e9f474f316590f480b976Yang Ni mContext->addForEach(FD); 6411946749cebf4a64341d8210890688fef7d958c22Yang Ni } 6421946749cebf4a64341d8210890688fef7d958c22Yang Ni // Look for any kernel launch calls and translate them into using the 6431946749cebf4a64341d8210890688fef7d958c22Yang Ni // internal API. 64440bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni // Report a compiler error on kernel launches inside a kernel. 6459319dfc974a82794d46e9f474f316590f480b976Yang Ni mForEachHandler.handleForEachCalls(FD, getTargetAPI()); 646fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni } 647fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni } 6488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 649fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni 6508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet return mGen->HandleTopLevelDecl(D); 6518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet} 6528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 6538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPre(clang::ASTContext &C) { 6548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 6558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 6565e306b944425a952fe744f59d828538137a59375David Gross if (!mContext->processReducePragmas(this)) 65765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross return; 65865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross 6598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // If we have an invalid RS/FS AST, don't check further. 6608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (!mASTChecker.Validate()) { 6618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet return; 6628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 6638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 6648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (mIsFilterscript) { 6658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mContext->addPragma("rs_fp_relaxed", ""); 6668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 6678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 6688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet int version = mContext->getVersion(); 6698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (version == 0) { 6708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Not setting a version is an error 6718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mDiagEngine.Report( 6728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()), 6738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mDiagEngine.getCustomDiagID( 6748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet clang::DiagnosticsEngine::Error, 6758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet "missing pragma for version in source file")); 6768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } else { 6778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet slangAssert(version == 1); 6788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 6798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 6808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (mContext->getReflectJavaPackageName().empty()) { 6818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mDiagEngine.Report( 6828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()), 6838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error, 6848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet "missing \"#pragma rs " 6858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet "java_package_name(com.foo.bar)\" " 6868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet "in source file")); 6878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet return; 6888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 6898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 6908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Create a static global destructor if necessary (to handle RS object 6918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // runtime cleanup). 6928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor(); 6938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (FD) { 6948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet HandleTopLevelDecl(clang::DeclGroupRef(FD)); 6958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 6968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 6978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Process any static function declarations 6988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(), 6998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet E = TUDecl->decls_end(); I != E; I++) { 7008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if ((I->getKind() >= clang::Decl::firstFunction) && 7018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet (I->getKind() <= clang::Decl::lastFunction)) { 7028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I); 7038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (FD && !FD->isGlobal()) { 7048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet AnnotateFunction(FD); 7058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 7068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 7078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 7088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet} 7098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 7108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet/////////////////////////////////////////////////////////////////////////////// 7118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportVarInfo(llvm::Module *M) { 7128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet int slotCount = 0; 7138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (mExportVarMetadata == nullptr) 7148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN); 7158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 7168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::SmallVector<llvm::Metadata *, 2> ExportVarInfo; 7178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 7188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // We emit slot information (#rs_object_slots) for any reference counted 7198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // RS type or pointer (which can also be bound). 7208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 7218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(), 7228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet E = mContext->export_vars_end(); 7238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet I != E; 7248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet I++) { 7258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet const RSExportVar *EV = *I; 7268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet const RSExportType *ET = EV->getType(); 7278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet bool countsAsRSObject = false; 7288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 7298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Variable name 7308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportVarInfo.push_back( 7318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDString::get(mLLVMContext, EV->getName().c_str())); 7328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 7338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Type name 7348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet switch (ET->getClass()) { 7358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet case RSExportType::ExportClassPrimitive: { 7368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet const RSExportPrimitiveType *PT = 7378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet static_cast<const RSExportPrimitiveType*>(ET); 7388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportVarInfo.push_back( 7398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDString::get( 740b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar mLLVMContext, llvm::utostr(PT->getType()))); 7418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (PT->isRSObjectType()) { 7428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet countsAsRSObject = true; 7438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 7448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet break; 7458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 7468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet case RSExportType::ExportClassPointer: { 7478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportVarInfo.push_back( 7488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDString::get( 7498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET) 7508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ->getPointeeType()->getName()).c_str())); 7518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet break; 7528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 7538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet case RSExportType::ExportClassMatrix: { 7548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportVarInfo.push_back( 7558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDString::get( 756b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar mLLVMContext, llvm::utostr( 7578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet /* TODO Strange value. This pushes just a number, quite 7588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet * different than the other cases. What is this used for? 7598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet * These are the metadata values that some partner drivers 7608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet * want to reference (for TBAA, etc.). We may want to look 7618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet * at whether these provide any reasonable value (or have 7628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet * distinct enough values to actually depend on). 7638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet */ 7648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet DataTypeRSMatrix2x2 + 7658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet static_cast<const RSExportMatrixType*>(ET)->getDim() - 2))); 7668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet break; 7678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 7688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet case RSExportType::ExportClassVector: 7698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet case RSExportType::ExportClassConstantArray: 7708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet case RSExportType::ExportClassRecord: { 7718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportVarInfo.push_back( 7728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDString::get(mLLVMContext, 7738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet EV->getType()->getName().c_str())); 7748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet break; 7758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 7768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 7778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 7788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mExportVarMetadata->addOperand( 7798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDNode::get(mLLVMContext, ExportVarInfo)); 7808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportVarInfo.clear(); 7818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 7828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (mRSObjectSlotsMetadata == nullptr) { 7838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mRSObjectSlotsMetadata = 7848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN); 7858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 7868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 7878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (countsAsRSObject) { 7888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext, 789b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar llvm::MDString::get(mLLVMContext, llvm::utostr(slotCount)))); 7908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 7918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 7928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet slotCount++; 7938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 7948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet} 7958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 7963a6750f246eed4168351786074691e8eeee5b175David Gross// A similar algorithm is present in Backend::PadStruct(). 7973a6750f246eed4168351786074691e8eeee5b175David Grossstatic void PadHelperFunctionStruct(llvm::Module *M, 7983a6750f246eed4168351786074691e8eeee5b175David Gross llvm::StructType **paddedStructType, 7993a6750f246eed4168351786074691e8eeee5b175David Gross std::vector<unsigned> *origFieldNumToPaddedFieldNum, 8003a6750f246eed4168351786074691e8eeee5b175David Gross llvm::StructType *origStructType) { 8013a6750f246eed4168351786074691e8eeee5b175David Gross slangAssert(origFieldNumToPaddedFieldNum->empty()); 8023a6750f246eed4168351786074691e8eeee5b175David Gross origFieldNumToPaddedFieldNum->resize(2 * origStructType->getNumElements()); 8033a6750f246eed4168351786074691e8eeee5b175David Gross 8043a6750f246eed4168351786074691e8eeee5b175David Gross llvm::LLVMContext &llvmContext = M->getContext(); 8053a6750f246eed4168351786074691e8eeee5b175David Gross 8063a6750f246eed4168351786074691e8eeee5b175David Gross const llvm::DataLayout *DL = &M->getDataLayout(); 8073a6750f246eed4168351786074691e8eeee5b175David Gross const llvm::StructLayout *SL = DL->getStructLayout(origStructType); 8083a6750f246eed4168351786074691e8eeee5b175David Gross 8093a6750f246eed4168351786074691e8eeee5b175David Gross // Field types -- including any padding fields we need to insert. 8103a6750f246eed4168351786074691e8eeee5b175David Gross std::vector<llvm::Type *> paddedFieldTypes; 8113a6750f246eed4168351786074691e8eeee5b175David Gross paddedFieldTypes.reserve(2 * origStructType->getNumElements()); 8123a6750f246eed4168351786074691e8eeee5b175David Gross 8133a6750f246eed4168351786074691e8eeee5b175David Gross // Is there any padding in this struct? 8143a6750f246eed4168351786074691e8eeee5b175David Gross bool foundPadding = false; 8153a6750f246eed4168351786074691e8eeee5b175David Gross 8163a6750f246eed4168351786074691e8eeee5b175David Gross llvm::Type *const byteType = llvm::Type::getInt8Ty(llvmContext); 8173a6750f246eed4168351786074691e8eeee5b175David Gross unsigned origFieldNum = 0, paddedFieldNum = 0; 8183a6750f246eed4168351786074691e8eeee5b175David Gross uint64_t fieldPrePaddingOffset = 0; // byte offset of pre-field padding within struct 8193a6750f246eed4168351786074691e8eeee5b175David Gross for (llvm::Type *fieldType : origStructType->elements()) { 8203a6750f246eed4168351786074691e8eeee5b175David Gross const uint64_t fieldOffset = SL->getElementOffset(origFieldNum); 8213a6750f246eed4168351786074691e8eeee5b175David Gross const size_t prePadding = fieldOffset - fieldPrePaddingOffset; 8223a6750f246eed4168351786074691e8eeee5b175David Gross if (prePadding != 0) { 8233a6750f246eed4168351786074691e8eeee5b175David Gross foundPadding = true; 8243a6750f246eed4168351786074691e8eeee5b175David Gross paddedFieldTypes.push_back(llvm::ArrayType::get(byteType, prePadding)); 8253a6750f246eed4168351786074691e8eeee5b175David Gross ++paddedFieldNum; 8263a6750f246eed4168351786074691e8eeee5b175David Gross } 8273a6750f246eed4168351786074691e8eeee5b175David Gross paddedFieldTypes.push_back(fieldType); 8283a6750f246eed4168351786074691e8eeee5b175David Gross (*origFieldNumToPaddedFieldNum)[origFieldNum] = paddedFieldNum; 8293a6750f246eed4168351786074691e8eeee5b175David Gross 8303a6750f246eed4168351786074691e8eeee5b175David Gross // get ready for the next field 8313a6750f246eed4168351786074691e8eeee5b175David Gross fieldPrePaddingOffset = fieldOffset + DL->getTypeAllocSize(fieldType); 8323a6750f246eed4168351786074691e8eeee5b175David Gross ++origFieldNum; 8333a6750f246eed4168351786074691e8eeee5b175David Gross ++paddedFieldNum; 8343a6750f246eed4168351786074691e8eeee5b175David Gross } 8353a6750f246eed4168351786074691e8eeee5b175David Gross 8363a6750f246eed4168351786074691e8eeee5b175David Gross // In order to ensure that the front end (including reflected code) 8373a6750f246eed4168351786074691e8eeee5b175David Gross // and back end agree on struct size (not just field offsets) we may 8383a6750f246eed4168351786074691e8eeee5b175David Gross // need to add explicit tail padding, just as we'e added explicit 8393a6750f246eed4168351786074691e8eeee5b175David Gross // padding between fields. 8403a6750f246eed4168351786074691e8eeee5b175David Gross slangAssert(SL->getSizeInBytes() >= fieldPrePaddingOffset); 8413a6750f246eed4168351786074691e8eeee5b175David Gross if (const size_t tailPadding = SL->getSizeInBytes() - fieldPrePaddingOffset) { 8423a6750f246eed4168351786074691e8eeee5b175David Gross foundPadding = true; 8433a6750f246eed4168351786074691e8eeee5b175David Gross paddedFieldTypes.push_back(llvm::ArrayType::get(byteType, tailPadding)); 8443a6750f246eed4168351786074691e8eeee5b175David Gross } 8453a6750f246eed4168351786074691e8eeee5b175David Gross 8463a6750f246eed4168351786074691e8eeee5b175David Gross *paddedStructType = (foundPadding 8473a6750f246eed4168351786074691e8eeee5b175David Gross ? llvm::StructType::get(llvmContext, paddedFieldTypes) 8483a6750f246eed4168351786074691e8eeee5b175David Gross : origStructType); 8493a6750f246eed4168351786074691e8eeee5b175David Gross} 8503a6750f246eed4168351786074691e8eeee5b175David Gross 8518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportFunctionInfo(llvm::Module *M) { 8528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (mExportFuncMetadata == nullptr) 8538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mExportFuncMetadata = 8548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN); 8558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 8568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::SmallVector<llvm::Metadata *, 1> ExportFuncInfo; 8578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 8588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet for (RSContext::const_export_func_iterator 8598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet I = mContext->export_funcs_begin(), 8608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet E = mContext->export_funcs_end(); 8618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet I != E; 8628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet I++) { 8638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet const RSExportFunc *EF = *I; 8648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 8658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Function name 8668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (!EF->hasParam()) { 8678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext, 8688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet EF->getName().c_str())); 8698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } else { 8708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::Function *F = M->getFunction(EF->getName()); 8718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::Function *HelperFunction; 8728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet const std::string HelperFunctionName(".helper_" + EF->getName()); 8738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 8748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet slangAssert(F && "Function marked as exported disappeared in Bitcode"); 8758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 8768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Create helper function 8778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet { 8783a6750f246eed4168351786074691e8eeee5b175David Gross llvm::StructType *OrigHelperFunctionParameterTy = nullptr; 8793a6750f246eed4168351786074691e8eeee5b175David Gross llvm::StructType *PaddedHelperFunctionParameterTy = nullptr; 8803a6750f246eed4168351786074691e8eeee5b175David Gross 8813a6750f246eed4168351786074691e8eeee5b175David Gross std::vector<unsigned> OrigFieldNumToPaddedFieldNum; 8828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet std::vector<bool> isStructInput; 8838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 8848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (!F->getArgumentList().empty()) { 8858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet std::vector<llvm::Type*> HelperFunctionParameterTys; 8868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet for (llvm::Function::arg_iterator AI = F->arg_begin(), 8878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet AE = F->arg_end(); AI != AE; AI++) { 8888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (AI->getType()->isPointerTy() && AI->getType()->getPointerElementType()->isStructTy()) { 8898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet HelperFunctionParameterTys.push_back(AI->getType()->getPointerElementType()); 8908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet isStructInput.push_back(true); 8918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } else { 8928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet HelperFunctionParameterTys.push_back(AI->getType()); 8938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet isStructInput.push_back(false); 8948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 8958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 8963a6750f246eed4168351786074691e8eeee5b175David Gross OrigHelperFunctionParameterTy = 8978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys); 8983a6750f246eed4168351786074691e8eeee5b175David Gross PadHelperFunctionStruct(M, 8993a6750f246eed4168351786074691e8eeee5b175David Gross &PaddedHelperFunctionParameterTy, &OrigFieldNumToPaddedFieldNum, 9003a6750f246eed4168351786074691e8eeee5b175David Gross OrigHelperFunctionParameterTy); 9018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 9028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9033a6750f246eed4168351786074691e8eeee5b175David Gross if (!EF->checkParameterPacketType(OrigHelperFunctionParameterTy)) { 9048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet fprintf(stderr, "Failed to export function %s: parameter type " 9058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet "mismatch during creation of helper function.\n", 9068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet EF->getName().c_str()); 9078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet const RSExportRecordType *Expected = EF->getParamPacketType(); 9098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (Expected) { 9108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet fprintf(stderr, "Expected:\n"); 9118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet Expected->getLLVMType()->dump(); 9128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 9133a6750f246eed4168351786074691e8eeee5b175David Gross if (OrigHelperFunctionParameterTy) { 9148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet fprintf(stderr, "Got:\n"); 9153a6750f246eed4168351786074691e8eeee5b175David Gross OrigHelperFunctionParameterTy->dump(); 9168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 9178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 9188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet std::vector<llvm::Type*> Params; 9203a6750f246eed4168351786074691e8eeee5b175David Gross if (PaddedHelperFunctionParameterTy) { 9218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::PointerType *HelperFunctionParameterTyP = 9223a6750f246eed4168351786074691e8eeee5b175David Gross llvm::PointerType::getUnqual(PaddedHelperFunctionParameterTy); 9238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet Params.push_back(HelperFunctionParameterTyP); 9248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 9258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::FunctionType * HelperFunctionType = 9278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::FunctionType::get(F->getReturnType(), 9288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet Params, 9298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet /* IsVarArgs = */false); 9308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet HelperFunction = 9328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::Function::Create(HelperFunctionType, 9338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::GlobalValue::ExternalLinkage, 9348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet HelperFunctionName, 9358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet M); 9368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet HelperFunction->addFnAttr(llvm::Attribute::NoInline); 9388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet HelperFunction->setCallingConv(F->getCallingConv()); 9398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Create helper function body 9418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet { 9428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::Argument *HelperFunctionParameter = 9438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet &(*HelperFunction->arg_begin()); 9448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::BasicBlock *BB = 9458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction); 9468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB); 9478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::SmallVector<llvm::Value*, 6> Params; 9488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::Value *Idx[2]; 9498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet Idx[0] = 9518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0); 9528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // getelementptr and load instruction for all elements in 9548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // parameter .p 9553a6750f246eed4168351786074691e8eeee5b175David Gross for (size_t origFieldNum = 0; origFieldNum < EF->getNumParameters(); origFieldNum++) { 9568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // getelementptr 9578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet Idx[1] = llvm::ConstantInt::get( 9583a6750f246eed4168351786074691e8eeee5b175David Gross llvm::Type::getInt32Ty(mLLVMContext), OrigFieldNumToPaddedFieldNum[origFieldNum]); 9598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::Value *Ptr = NULL; 9618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx); 9638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Load is only required for non-struct ptrs 9653a6750f246eed4168351786074691e8eeee5b175David Gross if (isStructInput[origFieldNum]) { 9668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet Params.push_back(Ptr); 9678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } else { 9688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::Value *V = IB->CreateLoad(Ptr); 9698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet Params.push_back(V); 9708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 9718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 9728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Call and pass the all elements as parameter to F 9748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::CallInst *CI = IB->CreateCall(F, Params); 9758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet CI->setCallingConv(F->getCallingConv()); 9778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 978fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext)) { 9798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet IB->CreateRetVoid(); 980fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni } else { 9818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet IB->CreateRet(CI); 982fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni } 9838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet delete IB; 9858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 9868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 9878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportFuncInfo.push_back( 9898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str())); 9908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 9918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mExportFuncMetadata->addOperand( 9938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDNode::get(mLLVMContext, ExportFuncInfo)); 9948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportFuncInfo.clear(); 9958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 9968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet} 9978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 9988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportForEachInfo(llvm::Module *M) { 9998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (mExportForEachNameMetadata == nullptr) { 10008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mExportForEachNameMetadata = 10018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN); 10028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 10038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (mExportForEachSignatureMetadata == nullptr) { 10048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mExportForEachSignatureMetadata = 10058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN); 10068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 10078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 10088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::SmallVector<llvm::Metadata *, 1> ExportForEachName; 10098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::SmallVector<llvm::Metadata *, 1> ExportForEachInfo; 10108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 10118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet for (RSContext::const_export_foreach_iterator 10128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet I = mContext->export_foreach_begin(), 10138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet E = mContext->export_foreach_end(); 10148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet I != E; 10158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet I++) { 10168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet const RSExportForEach *EFE = *I; 10178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 10188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportForEachName.push_back( 10198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDString::get(mLLVMContext, EFE->getName().c_str())); 10208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 10218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mExportForEachNameMetadata->addOperand( 10228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDNode::get(mLLVMContext, ExportForEachName)); 10238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportForEachName.clear(); 10248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 10258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportForEachInfo.push_back( 10268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDString::get(mLLVMContext, 1027b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar llvm::utostr(EFE->getSignatureMetadata()))); 10288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 10298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mExportForEachSignatureMetadata->addOperand( 10308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDNode::get(mLLVMContext, ExportForEachInfo)); 10318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportForEachInfo.clear(); 10328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 10338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet} 10348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 10358ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Grossvoid Backend::dumpExportReduceInfo(llvm::Module *M) { 10368ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross if (!mExportReduceMetadata) { 10378ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross mExportReduceMetadata = 10388ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross M->getOrInsertNamedMetadata(RS_EXPORT_REDUCE_MN); 103915e44e66adc350adb4fe0533a442092c64333ab5David Gross } 104015e44e66adc350adb4fe0533a442092c64333ab5David Gross 10418ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross llvm::SmallVector<llvm::Metadata *, 6> ExportReduceInfo; 10428ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross // Add operand to ExportReduceInfo, padding out missing operands with 104315e44e66adc350adb4fe0533a442092c64333ab5David Gross // nullptr. 10448ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross auto addOperand = [&ExportReduceInfo](uint32_t Idx, llvm::Metadata *N) { 10458ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross while (Idx > ExportReduceInfo.size()) 10468ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross ExportReduceInfo.push_back(nullptr); 10478ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross ExportReduceInfo.push_back(N); 104815e44e66adc350adb4fe0533a442092c64333ab5David Gross }; 10498ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross // Add string operand to ExportReduceInfo, padding out missing operands 105015e44e66adc350adb4fe0533a442092c64333ab5David Gross // with nullptr. 105115e44e66adc350adb4fe0533a442092c64333ab5David Gross // If string is empty, then do not add it unless Always is true. 105215e44e66adc350adb4fe0533a442092c64333ab5David Gross auto addString = [&addOperand, this](uint32_t Idx, const std::string &S, 105315e44e66adc350adb4fe0533a442092c64333ab5David Gross bool Always = true) { 105415e44e66adc350adb4fe0533a442092c64333ab5David Gross if (Always || !S.empty()) 105515e44e66adc350adb4fe0533a442092c64333ab5David Gross addOperand(Idx, llvm::MDString::get(mLLVMContext, S)); 105615e44e66adc350adb4fe0533a442092c64333ab5David Gross }; 105715e44e66adc350adb4fe0533a442092c64333ab5David Gross 105815e44e66adc350adb4fe0533a442092c64333ab5David Gross // Add the description of the reduction kernels to the metadata node. 10598ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross for (auto I = mContext->export_reduce_begin(), 10608ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross E = mContext->export_reduce_end(); 106115e44e66adc350adb4fe0533a442092c64333ab5David Gross I != E; ++I) { 10628ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross ExportReduceInfo.clear(); 106315e44e66adc350adb4fe0533a442092c64333ab5David Gross 106465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross int Idx = 0; 106565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross 106665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross addString(Idx++, (*I)->getNameReduce()); 106765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross 1068b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar addOperand(Idx++, llvm::MDString::get(mLLVMContext, llvm::utostr((*I)->getAccumulatorTypeSize()))); 106915e44e66adc350adb4fe0533a442092c64333ab5David Gross 107015e44e66adc350adb4fe0533a442092c64333ab5David Gross llvm::SmallVector<llvm::Metadata *, 2> Accumulator; 107115e44e66adc350adb4fe0533a442092c64333ab5David Gross Accumulator.push_back( 107215e44e66adc350adb4fe0533a442092c64333ab5David Gross llvm::MDString::get(mLLVMContext, (*I)->getNameAccumulator())); 107315e44e66adc350adb4fe0533a442092c64333ab5David Gross Accumulator.push_back(llvm::MDString::get( 107415e44e66adc350adb4fe0533a442092c64333ab5David Gross mLLVMContext, 1075b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar llvm::utostr((*I)->getAccumulatorSignatureMetadata()))); 107665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross addOperand(Idx++, llvm::MDTuple::get(mLLVMContext, Accumulator)); 107715e44e66adc350adb4fe0533a442092c64333ab5David Gross 107865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross addString(Idx++, (*I)->getNameInitializer(), false); 107965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross addString(Idx++, (*I)->getNameCombiner(), false); 108065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross addString(Idx++, (*I)->getNameOutConverter(), false); 108165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross addString(Idx++, (*I)->getNameHalter(), false); 108215e44e66adc350adb4fe0533a442092c64333ab5David Gross 10838ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross mExportReduceMetadata->addOperand( 10848ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross llvm::MDTuple::get(mLLVMContext, ExportReduceInfo)); 108515e44e66adc350adb4fe0533a442092c64333ab5David Gross } 108615e44e66adc350adb4fe0533a442092c64333ab5David Gross} 108715e44e66adc350adb4fe0533a442092c64333ab5David Gross 10888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportTypeInfo(llvm::Module *M) { 10898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::SmallVector<llvm::Metadata *, 1> ExportTypeInfo; 10908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 10918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet for (RSContext::const_export_type_iterator 10928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet I = mContext->export_types_begin(), 10938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet E = mContext->export_types_end(); 10948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet I != E; 10958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet I++) { 10968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // First, dump type name list to export 10978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet const RSExportType *ET = I->getValue(); 10988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 10998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportTypeInfo.clear(); 11008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Type name 11018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet ExportTypeInfo.push_back( 11028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDString::get(mLLVMContext, ET->getName().c_str())); 11038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (ET->getClass() == RSExportType::ExportClassRecord) { 11058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet const RSExportRecordType *ERT = 11068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet static_cast<const RSExportRecordType*>(ET); 11078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (mExportTypeMetadata == nullptr) 11098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mExportTypeMetadata = 11108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN); 11118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet mExportTypeMetadata->addOperand( 11138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDNode::get(mLLVMContext, ExportTypeInfo)); 11148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // Now, export struct field information to %[struct name] 11168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet std::string StructInfoMetadataName("%"); 11178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet StructInfoMetadataName.append(ET->getName()); 11188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::NamedMDNode *StructInfoMetadata = 11198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet M->getOrInsertNamedMetadata(StructInfoMetadataName); 11208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::SmallVector<llvm::Metadata *, 3> FieldInfo; 11218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet slangAssert(StructInfoMetadata->getNumOperands() == 0 && 11238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet "Metadata with same name was created before"); 11248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 11258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet FE = ERT->fields_end(); 11268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet FI != FE; 11278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet FI++) { 11288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet const RSExportRecordType::Field *F = *FI; 11298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // 1. field name 11318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet FieldInfo.push_back(llvm::MDString::get(mLLVMContext, 11328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet F->getName().c_str())); 11338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet // 2. field type name 11358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet FieldInfo.push_back( 11368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDString::get(mLLVMContext, 11378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet F->getType()->getName().c_str())); 11388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet StructInfoMetadata->addOperand( 11408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet llvm::MDNode::get(mLLVMContext, FieldInfo)); 11418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet FieldInfo.clear(); 11428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 11438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } // ET->getClass() == RSExportType::ExportClassRecord 11448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 11458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet} 11468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPost(llvm::Module *M) { 11488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (!mContext->is64Bit()) { 11508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet M->setDataLayout("e-p:32:32-i64:64-v128:64:128-n32-S64"); 11518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet } 11528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 115365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (!mContext->processExports()) 11548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet return; 11558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (mContext->hasExportVar()) 11578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet dumpExportVarInfo(M); 11588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (mContext->hasExportFunc()) 11608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet dumpExportFunctionInfo(M); 11618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (mContext->hasExportForEach()) 11638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet dumpExportForEachInfo(M); 11648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 11658ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross if (mContext->hasExportReduce()) 11668ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross dumpExportReduceInfo(M); 116715e44e66adc350adb4fe0533a442092c64333ab5David Gross 11688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet if (mContext->hasExportType()) 11698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet dumpExportTypeInfo(M); 11708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet} 11718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet 1172e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1173