11f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan/* 2db169187dea4602e4ad32058762d23d474753fd0Stephen Hines * Copyright 2010-2012, The Android Open Source Project 31f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * 41f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * Licensed under the Apache License, Version 2.0 (the "License"); 51f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * you may not use this file except in compliance with the License. 61f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * You may obtain a copy of the License at 71f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * 81f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * http://www.apache.org/licenses/LICENSE-2.0 91f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * 101f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * Unless required by applicable law or agreed to in writing, software 111f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * distributed under the License is distributed on an "AS IS" BASIS, 121f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * See the License for the specific language governing permissions and 141f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * limitations under the License. 151f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan */ 161f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan 17c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Compiler.h" 181f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan 19ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang#include <llvm/Analysis/Passes.h> 201bd9f627fa0affb457507e86b0b6684c695fe726Stephen Hines#include <llvm/Analysis/TargetTransformInfo.h> 21ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang#include <llvm/CodeGen/RegAllocRegistry.h> 221bd9f627fa0affb457507e86b0b6684c695fe726Stephen Hines#include <llvm/IR/LegacyPassManager.h> 23b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/Module.h> 24ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang#include <llvm/Support/TargetRegistry.h> 25ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang#include <llvm/Support/raw_ostream.h> 26b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/DataLayout.h> 27579361346abc6696c805e3904a18178ebce4e4a3Stephen Hines#include <llvm/Target/TargetSubtargetInfo.h> 28ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang#include <llvm/Target/TargetMachine.h> 29ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang#include <llvm/Transforms/IPO.h> 302f6103bb820139d19f709e687f5bf4f86226057eTobias Grosser#include <llvm/Transforms/IPO/PassManagerBuilder.h> 31ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang#include <llvm/Transforms/Scalar.h> 3250f5eb4b27ce6dd2a02cf389ac2acfa95c6939f1Tim Murray#include <llvm/Transforms/Vectorize.h> 33ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 34b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes#include "bcc/Assert.h" 359e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar#include "bcc/Config/Config.h" 36b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes#include "bcc/Renderscript/RSScript.h" 37b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes#include "bcc/Renderscript/RSTransforms.h" 3857fd9f882f3359be4201c42b02aebf785d311df2David Gross#include "bcc/Renderscript/RSUtils.h" 39c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Script.h" 40c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Source.h" 41c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Support/CompilerConfig.h" 42ef73a242762bcd8113b9b65ceccbe7d909b5acbcZonr Chang#include "bcc/Support/Log.h" 43c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Support/OutputFile.h" 44b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes#include "bcinfo/MetadataExtractor.h" 45fb81ec1a875d13d9750006313b9123903336101dStephen Hines#include "rsDefines.h" 46ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 4710ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines#include <string> 4810ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines 49ade92778b99382413ff9c556c724dd3f447e5dfbZonr Changusing namespace bcc; 50ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 51ade92778b99382413ff9c556c724dd3f447e5dfbZonr Changconst char *Compiler::GetErrorString(enum ErrorCode pErrCode) { 525b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser switch (pErrCode) { 535b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser case kSuccess: 545b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser return "Successfully compiled."; 555b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser case kInvalidConfigNoTarget: 56900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes return "Invalid compiler config supplied (getTarget() returns nullptr.) " 575b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser "(missing call to CompilerConfig::initialize()?)"; 585b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser case kErrCreateTargetMachine: 595b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser return "Failed to create llvm::TargetMachine."; 605b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser case kErrSwitchTargetMachine: 615b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser return "Failed to switch llvm::TargetMachine."; 625b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser case kErrNoTargetMachine: 635b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser return "Failed to compile the script since there's no available " 645b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser "TargetMachine. (missing call to Compiler::config()?)"; 655b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser case kErrMaterialization: 665b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser return "Failed to materialize the module."; 675b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser case kErrInvalidOutputFileState: 685b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser return "Supplied output file was invalid (in the error state.)"; 695b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser case kErrPrepareOutput: 705b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser return "Failed to prepare file for output."; 715b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser case kPrepareCodeGenPass: 725b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser return "Failed to construct pass list for code-generation."; 73b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes case kErrCustomPasses: 74b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes return "Error occurred while adding custom passes."; 755b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser case kErrInvalidSource: 765b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser return "Error loading input bitcode"; 771e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar case kIllegalGlobalFunction: 781e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar return "Use of undefined external function"; 799e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar case kErrInvalidTargetMachine: 809e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar return "Invalid/unexpected llvm::TargetMachine."; 814a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines } 824a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines 835b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser // This assert should never be reached as the compiler verifies that the 845b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser // above switch coveres all enum values. 85c2ca742d7d0197c52e49467862844463fb42280fDavid Gross bccAssert(false && "Unknown error code encountered"); 865b7f52aff2030d520ee2ac6d3ac7d917f38d550cTobias Grosser return ""; 874a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines} 884a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines 89ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang//===----------------------------------------------------------------------===// 90ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang// Instance Methods 91ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang//===----------------------------------------------------------------------===// 92b4447cd2b14f53efd9102d28da48000be7b2d4fdChris WailesCompiler::Compiler() : mTarget(nullptr), mEnableOpt(true) { 93ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang return; 944a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines} 954a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines 96900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris WailesCompiler::Compiler(const CompilerConfig &pConfig) : mTarget(nullptr), 97b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes mEnableOpt(true) { 98ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang const std::string &triple = pConfig.getTriple(); 99ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 100ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang enum ErrorCode err = config(pConfig); 101ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang if (err != kSuccess) { 102ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang ALOGE("%s (%s, features: %s)", GetErrorString(err), 103ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang triple.c_str(), pConfig.getFeatureString().c_str()); 104ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang return; 105ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang } 1064a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines 1071f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan return; 1081f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan} 1091f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan 110ade92778b99382413ff9c556c724dd3f447e5dfbZonr Changenum Compiler::ErrorCode Compiler::config(const CompilerConfig &pConfig) { 111900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes if (pConfig.getTarget() == nullptr) { 112ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang return kInvalidConfigNoTarget; 1131f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan } 1144a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines 115ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang llvm::TargetMachine *new_target = 116ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang (pConfig.getTarget())->createTargetMachine(pConfig.getTriple(), 117ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang pConfig.getCPU(), 118ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang pConfig.getFeatureString(), 119ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang pConfig.getTargetOptions(), 120ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang pConfig.getRelocationModel(), 121ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang pConfig.getCodeModel(), 122ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang pConfig.getOptimizationLevel()); 123ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 124900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes if (new_target == nullptr) { 125900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes return ((mTarget != nullptr) ? kErrSwitchTargetMachine : 126b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes kErrCreateTargetMachine); 127094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 128094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 129ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang // Replace the old TargetMachine. 130ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang delete mTarget; 131ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang mTarget = new_target; 132094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 133ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang // Adjust register allocation policy according to the optimization level. 134094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // createFastRegisterAllocator: fast but bad quality 135094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // createLinearScanRegisterAllocator: not so fast but good quality 136ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang if ((pConfig.getOptimizationLevel() == llvm::CodeGenOpt::None)) { 137ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang llvm::RegisterRegAlloc::setDefault(llvm::createFastRegisterAllocator); 138ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang } else { 139ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang llvm::RegisterRegAlloc::setDefault(llvm::createGreedyRegisterAllocator); 1404a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines } 1414a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines 142ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang return kSuccess; 1434a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines} 1444a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines 145ade92778b99382413ff9c556c724dd3f447e5dfbZonr ChangCompiler::~Compiler() { 146ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang delete mTarget; 1474a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines} 1484a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines 1491e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar 1505aefc98db2dc14a703ce3d4f134565b834686552David Gross// This function has complete responsibility for creating and executing the 1515aefc98db2dc14a703ce3d4f134565b834686552David Gross// exact list of compiler passes. 152b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailesenum Compiler::ErrorCode Compiler::runPasses(Script &pScript, 15398137cca7eebca946b869b010fef2821c9bf4971Pirama Arumuga Nainar llvm::raw_pwrite_stream &pResult) { 154ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang // Pass manager for link-time optimization 1551e321862daea867b44700360c4827bcb7b97968aDean De Leo llvm::legacy::PassManager transformPasses; 156b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 157b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes // Empty MCContext. 158b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes llvm::MCContext *mc_context = nullptr; 1594a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines 1601e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add( 1611e321862daea867b44700360c4827bcb7b97968aDean De Leo createTargetTransformInfoWrapperPass(mTarget->getTargetIRAnalysis())); 162bb73b74a9f6ad26c2ab30557bfe6916a44ed75f6Tim Murray 1635aefc98db2dc14a703ce3d4f134565b834686552David Gross // Add some initial custom passes. 1641e321862daea867b44700360c4827bcb7b97968aDean De Leo addInvokeHelperPass(transformPasses); 1651e321862daea867b44700360c4827bcb7b97968aDean De Leo addExpandKernelPass(transformPasses); 16609c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo addDebugInfoPass(pScript, transformPasses); 1671e321862daea867b44700360c4827bcb7b97968aDean De Leo addInvariantPass(transformPasses); 1687a9a96766a6636218b516d61fbe47a99dea8afc4Dean De Leo if (mTarget->getOptLevel() != llvm::CodeGenOpt::None) { 1697a9a96766a6636218b516d61fbe47a99dea8afc4Dean De Leo if (!addInternalizeSymbolsPass(pScript, transformPasses)) 1707a9a96766a6636218b516d61fbe47a99dea8afc4Dean De Leo return kErrCustomPasses; 1717a9a96766a6636218b516d61fbe47a99dea8afc4Dean De Leo } 1721e321862daea867b44700360c4827bcb7b97968aDean De Leo addGlobalInfoPass(pScript, transformPasses); 1734a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines 174ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang if (mTarget->getOptLevel() == llvm::CodeGenOpt::None) { 1751e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add(llvm::createGlobalOptimizerPass()); 1761e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add(llvm::createConstantMergePass()); 177b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 178ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang } else { 1792f6103bb820139d19f709e687f5bf4f86226057eTobias Grosser // FIXME: Figure out which passes should be executed. 1802f6103bb820139d19f709e687f5bf4f86226057eTobias Grosser llvm::PassManagerBuilder Builder; 181579361346abc6696c805e3904a18178ebce4e4a3Stephen Hines Builder.Inliner = llvm::createFunctionInliningPass(); 1821e321862daea867b44700360c4827bcb7b97968aDean De Leo Builder.populateLTOPassManager(transformPasses); 18350f5eb4b27ce6dd2a02cf389ac2acfa95c6939f1Tim Murray 1847f59b5f76c7149b42ff6d4910c6f6165b3358e72Tim Murray /* FIXME: Reenable autovectorization after rebase. 1857f59b5f76c7149b42ff6d4910c6f6165b3358e72Tim Murray bug 19324423 18650f5eb4b27ce6dd2a02cf389ac2acfa95c6939f1Tim Murray // Add vectorization passes after LTO passes are in 18750f5eb4b27ce6dd2a02cf389ac2acfa95c6939f1Tim Murray // additional flag: -unroll-runtime 1881e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add(llvm::createLoopUnrollPass(-1, 16, 0, 1)); 18950f5eb4b27ce6dd2a02cf389ac2acfa95c6939f1Tim Murray // Need to pass appropriate flags here: -scalarize-load-store 1901e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add(llvm::createScalarizerPass()); 1911e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add(llvm::createCFGSimplificationPass()); 1921e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add(llvm::createScopedNoAliasAAPass()); 1931e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add(llvm::createScalarEvolutionAliasAnalysisPass()); 19450f5eb4b27ce6dd2a02cf389ac2acfa95c6939f1Tim Murray // additional flags: -slp-vectorize-hor -slp-vectorize-hor-store (unnecessary?) 1951e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add(llvm::createSLPVectorizerPass()); 1961e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add(llvm::createDeadCodeEliminationPass()); 1971e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add(llvm::createInstructionCombiningPass()); 1987f59b5f76c7149b42ff6d4910c6f6165b3358e72Tim Murray */ 199ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang } 200ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 2018c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // These passes have to come after LTO, since we don't want to examine 2028c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // functions that are never actually called. 2035aefc98db2dc14a703ce3d4f134565b834686552David Gross if (llvm::Triple(getTargetMachine().getTargetTriple()).getArch() == llvm::Triple::x86_64) 2041e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add(createRSX86_64CallConvPass()); // Add pass to correct calling convention for X86-64. 2051e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add(createRSIsThreadablePass()); // Add pass to mark script as threadable. 2069fe081b8bae8a95d903f8fa8dc0a7590ae706606Pirama Arumuga Nainar 2079fe081b8bae8a95d903f8fa8dc0a7590ae706606Pirama Arumuga Nainar // RSEmbedInfoPass needs to come after we have scanned for non-threadable 2089fe081b8bae8a95d903f8fa8dc0a7590ae706606Pirama Arumuga Nainar // functions. 2099fe081b8bae8a95d903f8fa8dc0a7590ae706606Pirama Arumuga Nainar // Script passed to RSCompiler must be a RSScript. 2109fe081b8bae8a95d903f8fa8dc0a7590ae706606Pirama Arumuga Nainar RSScript &script = static_cast<RSScript &>(pScript); 2119fe081b8bae8a95d903f8fa8dc0a7590ae706606Pirama Arumuga Nainar if (script.getEmbedInfo()) 2121e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.add(createRSEmbedInfoPass()); 2131e321862daea867b44700360c4827bcb7b97968aDean De Leo 2141e321862daea867b44700360c4827bcb7b97968aDean De Leo // Execute the passes. 2151e321862daea867b44700360c4827bcb7b97968aDean De Leo transformPasses.run(pScript.getSource().getModule()); 2161e321862daea867b44700360c4827bcb7b97968aDean De Leo 2171e321862daea867b44700360c4827bcb7b97968aDean De Leo // Run backend separately to avoid interference between debug metadata 2181e321862daea867b44700360c4827bcb7b97968aDean De Leo // generation and backend initialization. 2191e321862daea867b44700360c4827bcb7b97968aDean De Leo llvm::legacy::PassManager codeGenPasses; 2205db508c73e6177eb306bac4725616b7c001587c4Stephen Hines 221ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang // Add passes to the pass manager to emit machine code through MC layer. 2221e321862daea867b44700360c4827bcb7b97968aDean De Leo if (mTarget->addPassesToEmitMC(codeGenPasses, mc_context, pResult, 223ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang /* DisableVerify */false)) { 224ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang return kPrepareCodeGenPass; 225ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang } 226ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 227b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes // Execute the passes. 2281e321862daea867b44700360c4827bcb7b97968aDean De Leo codeGenPasses.run(pScript.getSource().getModule()); 229ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 230ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang return kSuccess; 231da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien} 232da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien 233ade92778b99382413ff9c556c724dd3f447e5dfbZonr Changenum Compiler::ErrorCode Compiler::compile(Script &pScript, 23498137cca7eebca946b869b010fef2821c9bf4971Pirama Arumuga Nainar llvm::raw_pwrite_stream &pResult, 23527fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser llvm::raw_ostream *IRStream) { 236ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang llvm::Module &module = pScript.getSource().getModule(); 237ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang enum ErrorCode err; 238ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 239900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes if (mTarget == nullptr) { 240ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang return kErrNoTargetMachine; 241ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang } 242ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 24310ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines const std::string &triple = module.getTargetTriple(); 2448e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar const llvm::DataLayout dl = getTargetMachine().createDataLayout(); 2458e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar unsigned int pointerSize = dl.getPointerSizeInBits(); 24610ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines if (triple == "armv7-none-linux-gnueabi") { 24710ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines if (pointerSize != 32) { 24810ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines return kErrInvalidSource; 24910ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines } 25010ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines } else if (triple == "aarch64-none-linux-gnueabi") { 25110ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines if (pointerSize != 64) { 25210ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines return kErrInvalidSource; 25310ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines } 25410ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines } else { 25510ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines return kErrInvalidSource; 25610ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines } 25710ee6af612d585301c6f2b2f0f04e9bc80b338bbStephen Hines 2589e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar if (getTargetMachine().getTargetTriple().getArch() == llvm::Triple::x86) { 2599e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar // Detect and fail if TargetMachine datalayout is different than what we 2609e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar // expect. This is to detect changes in default target layout for x86 and 2619e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar // update X86_CUSTOM_DL_STRING in include/bcc/Config/Config.h appropriately. 2629e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar if (dl.getStringRepresentation().compare(X86_DEFAULT_DL_STRING) != 0) { 2639e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar return kErrInvalidTargetMachine; 2649e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar } 2659e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar } 2669e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar 267cf8b2d0d2fcd7acf9769b3e1f26ac6e3a0a9b6e7David Gross // Sanitize module's target information. 2688e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar module.setTargetTriple(getTargetMachine().getTargetTriple().str()); 2698e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar module.setDataLayout(getTargetMachine().createDataLayout()); 270cf8b2d0d2fcd7acf9769b3e1f26ac6e3a0a9b6e7David Gross 271ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang // Materialize the bitcode module. 272900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes if (module.getMaterializer() != nullptr) { 273ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang // A module with non-null materializer means that it is a lazy-load module. 2748e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar // Materialize it now. This function returns false when the materialization 2758e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar // is successful. 2768e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar std::error_code ec = module.materializeAll(); 277c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray if (ec) { 278ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang ALOGE("Failed to materialize the module `%s'! (%s)", 279c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray module.getModuleIdentifier().c_str(), ec.message().c_str()); 280ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang return kErrMaterialization; 281ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang } 282ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang } 283fef9a1b0b772034b4f0894d1e2b29d1115617be0Zonr Chang 284b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes if ((err = runPasses(pScript, pResult)) != kSuccess) { 285ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang return err; 286ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang } 287ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 288b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes if (IRStream) { 28927fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser *IRStream << module; 290ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang } 291ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 292ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang return kSuccess; 2931f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan} 2941f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan 295ade92778b99382413ff9c556c724dd3f447e5dfbZonr Changenum Compiler::ErrorCode Compiler::compile(Script &pScript, 29627fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser OutputFile &pResult, 29727fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser llvm::raw_ostream *IRStream) { 298ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang // Check the state of the specified output file. 299ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang if (pResult.hasError()) { 300ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang return kErrInvalidOutputFileState; 301ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang } 302ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 303ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang // Open the output file decorated in llvm::raw_ostream. 30498137cca7eebca946b869b010fef2821c9bf4971Pirama Arumuga Nainar llvm::raw_pwrite_stream *out = pResult.dup(); 305900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes if (out == nullptr) { 306ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang return kErrPrepareOutput; 307ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang } 308ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 309ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang // Delegate the request. 31027fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser enum Compiler::ErrorCode err = compile(pScript, *out, IRStream); 31190cd3d1ec93c46389c00cd41375608632dd4ceb5Shih-wei Liao 312ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang // Close the output before return. 313ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang delete out; 314ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang 315ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang return err; 316ade92778b99382413ff9c556c724dd3f447e5dfbZonr Chang} 317b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 3181bd9f627fa0affb457507e86b0b6684c695fe726Stephen Hinesbool Compiler::addInternalizeSymbolsPass(Script &pScript, llvm::legacy::PassManager &pPM) { 319b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes // Add a pass to internalize the symbols that don't need to have global 320b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes // visibility. 321b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes RSScript &script = static_cast<RSScript &>(pScript); 322b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes llvm::Module &module = script.getSource().getModule(); 323b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes bcinfo::MetadataExtractor me(&module); 324b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes if (!me.extract()) { 325b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes bccAssert(false && "Could not extract metadata for module!"); 326b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes return false; 327b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes } 328b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 329b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes // The vector contains the symbols that should not be internalized. 330b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes std::vector<const char *> export_symbols; 331b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 332107f50d54d9606e495187d0e89225d3d9fdc1fa9Stephen Hines const char *sf[] = { 333fb81ec1a875d13d9750006313b9123903336101dStephen Hines kRoot, // Graphics drawing function or compute kernel. 334fb81ec1a875d13d9750006313b9123903336101dStephen Hines kInit, // Initialization routine called implicitly on startup. 335fb81ec1a875d13d9750006313b9123903336101dStephen Hines kRsDtor, // Static global destructor for a script instance. 336fb81ec1a875d13d9750006313b9123903336101dStephen Hines kRsInfo, // Variable containing string of RS metadata info. 337fb81ec1a875d13d9750006313b9123903336101dStephen Hines kRsGlobalEntries, // Optional number of global variables. 338fb81ec1a875d13d9750006313b9123903336101dStephen Hines kRsGlobalNames, // Optional global variable name info. 339fb81ec1a875d13d9750006313b9123903336101dStephen Hines kRsGlobalAddresses, // Optional global variable address info. 340fb81ec1a875d13d9750006313b9123903336101dStephen Hines kRsGlobalSizes, // Optional global variable size info. 341fb81ec1a875d13d9750006313b9123903336101dStephen Hines kRsGlobalProperties, // Optional global variable properties. 342fb81ec1a875d13d9750006313b9123903336101dStephen Hines nullptr // Must be nullptr-terminated. 343107f50d54d9606e495187d0e89225d3d9fdc1fa9Stephen Hines }; 344107f50d54d9606e495187d0e89225d3d9fdc1fa9Stephen Hines const char **special_functions = sf; 345b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes // Special RS functions should always be global symbols. 346b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes while (*special_functions != nullptr) { 347b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes export_symbols.push_back(*special_functions); 348b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes special_functions++; 349b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes } 350b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 351b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes // Visibility of symbols appeared in rs_export_var and rs_export_func should 352b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes // also be preserved. 353b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes size_t exportVarCount = me.getExportVarCount(); 354b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes size_t exportFuncCount = me.getExportFuncCount(); 355b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes size_t exportForEachCount = me.getExportForEachSignatureCount(); 3564e7a50685ae18a24087f6f2a51c604e71fab69e2Matt Wala size_t exportReduceCount = me.getExportReduceCount(); 357b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes const char **exportVarNameList = me.getExportVarNameList(); 358b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes const char **exportFuncNameList = me.getExportFuncNameList(); 359b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes const char **exportForEachNameList = me.getExportForEachNameList(); 360a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross const bcinfo::MetadataExtractor::Reduce *exportReduceList = me.getExportReduceList(); 361b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes size_t i; 362b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 363b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes for (i = 0; i < exportVarCount; ++i) { 364b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes export_symbols.push_back(exportVarNameList[i]); 365b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes } 366b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 367b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes for (i = 0; i < exportFuncCount; ++i) { 368b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes export_symbols.push_back(exportFuncNameList[i]); 369b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes } 370b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 371a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // Expanded foreach functions should not be internalized; nor should 372a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // general reduction initializer, combiner, and outconverter 373a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // functions. keep_funcs keeps the names of these functions around 374a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // until createInternalizePass() is finished making its own copy of 375a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // the visible symbols. 376c545d6f10fa4827de235b5f85b58e803eba725bcDavid Gross std::vector<std::string> keep_funcs; 377a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross keep_funcs.reserve(exportForEachCount + exportReduceCount*4); 3784e7a50685ae18a24087f6f2a51c604e71fab69e2Matt Wala 379b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes for (i = 0; i < exportForEachCount; ++i) { 380c545d6f10fa4827de235b5f85b58e803eba725bcDavid Gross keep_funcs.push_back(std::string(exportForEachNameList[i]) + ".expand"); 3814e7a50685ae18a24087f6f2a51c604e71fab69e2Matt Wala } 382c545d6f10fa4827de235b5f85b58e803eba725bcDavid Gross auto keepFuncsPushBackIfPresent = [&keep_funcs](const char *Name) { 383c545d6f10fa4827de235b5f85b58e803eba725bcDavid Gross if (Name) keep_funcs.push_back(Name); 384c545d6f10fa4827de235b5f85b58e803eba725bcDavid Gross }; 385a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross for (i = 0; i < exportReduceCount; ++i) { 386a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross keep_funcs.push_back(std::string(exportReduceList[i].mAccumulatorName) + ".expand"); 387a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross keepFuncsPushBackIfPresent(exportReduceList[i].mInitializerName); 388a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross if (exportReduceList[i].mCombinerName != nullptr) { 389a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross keep_funcs.push_back(exportReduceList[i].mCombinerName); 39057fd9f882f3359be4201c42b02aebf785d311df2David Gross } else { 391a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross keep_funcs.push_back(nameReduceCombinerFromAccumulator(exportReduceList[i].mAccumulatorName)); 39257fd9f882f3359be4201c42b02aebf785d311df2David Gross } 393a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross keepFuncsPushBackIfPresent(exportReduceList[i].mOutConverterName); 39479e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross } 395b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 396c545d6f10fa4827de235b5f85b58e803eba725bcDavid Gross for (auto &symbol_name : keep_funcs) { 3974e7a50685ae18a24087f6f2a51c604e71fab69e2Matt Wala export_symbols.push_back(symbol_name.c_str()); 398b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes } 399b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 40010f2a8f1d60724c306d01cdd0682e38122637502Pirama Arumuga Nainar // http://b/26165616 - WAR for this bug defines the __truncxfhf2 function in 40110f2a8f1d60724c306d01cdd0682e38122637502Pirama Arumuga Nainar // frameworks/rs/driver/runtime. Don't internalize this function for x86, so 40210f2a8f1d60724c306d01cdd0682e38122637502Pirama Arumuga Nainar // that a script can find and link against it. 40310f2a8f1d60724c306d01cdd0682e38122637502Pirama Arumuga Nainar llvm::Triple triple(getTargetMachine().getTargetTriple()); 40410f2a8f1d60724c306d01cdd0682e38122637502Pirama Arumuga Nainar if (triple.getArch() == llvm::Triple::x86) { 40510f2a8f1d60724c306d01cdd0682e38122637502Pirama Arumuga Nainar export_symbols.push_back("__truncxfhf2"); 40610f2a8f1d60724c306d01cdd0682e38122637502Pirama Arumuga Nainar } 40710f2a8f1d60724c306d01cdd0682e38122637502Pirama Arumuga Nainar 408b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes pPM.add(llvm::createInternalizePass(export_symbols)); 409b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 410b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes return true; 411b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes} 412b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 4135aefc98db2dc14a703ce3d4f134565b834686552David Grossvoid Compiler::addInvokeHelperPass(llvm::legacy::PassManager &pPM) { 414b7bce7436876884dfd78ec41d147ddbe47e37cbdTim Murray llvm::Triple arch(getTargetMachine().getTargetTriple()); 415b7bce7436876884dfd78ec41d147ddbe47e37cbdTim Murray if (arch.isArch64Bit()) { 416b7bce7436876884dfd78ec41d147ddbe47e37cbdTim Murray pPM.add(createRSInvokeHelperPass()); 417b7bce7436876884dfd78ec41d147ddbe47e37cbdTim Murray } 418b7bce7436876884dfd78ec41d147ddbe47e37cbdTim Murray} 419b7bce7436876884dfd78ec41d147ddbe47e37cbdTim Murray 42009c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leovoid Compiler::addDebugInfoPass(Script &pScript, llvm::legacy::PassManager &pPM) { 42109c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo if (pScript.getSource().getDebugInfoEnabled()) 42209c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo pPM.add(createRSAddDebugInfoPass()); 42309c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo} 42409c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 4254e7a50685ae18a24087f6f2a51c604e71fab69e2Matt Walavoid Compiler::addExpandKernelPass(llvm::legacy::PassManager &pPM) { 4264e7a50685ae18a24087f6f2a51c604e71fab69e2Matt Wala // Expand ForEach and reduce on CPU path to reduce launch overhead. 427b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes bool pEnableStepOpt = true; 4284e7a50685ae18a24087f6f2a51c604e71fab69e2Matt Wala pPM.add(createRSKernelExpandPass(pEnableStepOpt)); 429b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes} 430b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes 4315aefc98db2dc14a703ce3d4f134565b834686552David Grossvoid Compiler::addGlobalInfoPass(Script &pScript, llvm::legacy::PassManager &pPM) { 432750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // Add additional information about RS global variables inside the Module. 433750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines RSScript &script = static_cast<RSScript &>(pScript); 434750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines if (script.getEmbedGlobalInfo()) { 435750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines pPM.add(createRSGlobalInfoPass(script.getEmbedGlobalInfoSkipConstant())); 436750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } 437750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines} 438750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 4395aefc98db2dc14a703ce3d4f134565b834686552David Grossvoid Compiler::addInvariantPass(llvm::legacy::PassManager &pPM) { 4401d93a190e62ec1588b4724ca8759216b2d0b76d7David Gross // Mark Loads from RsExpandKernelDriverInfo as "load.invariant". 4411d93a190e62ec1588b4724ca8759216b2d0b76d7David Gross // Should run after ExpandForEach and before inlining. 4421d93a190e62ec1588b4724ca8759216b2d0b76d7David Gross pPM.add(createRSInvariantPass()); 4438c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar} 444ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar 445ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainarenum Compiler::ErrorCode Compiler::screenGlobalFunctions(Script &pScript) { 446ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar llvm::Module &module = pScript.getSource().getModule(); 447ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar 448ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar // Materialize the bitcode module in case this is a lazy-load module. Do not 449ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar // clear the materializer by calling materializeAllPermanently since the 450ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar // runtime library has not been merged into the module yet. 451ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar if (module.getMaterializer() != nullptr) { 452ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar std::error_code ec = module.materializeAll(); 453ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar if (ec) { 454ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar ALOGE("Failed to materialize module `%s' when screening globals! (%s)", 455ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar module.getModuleIdentifier().c_str(), ec.message().c_str()); 456ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar return kErrMaterialization; 457ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar } 458ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar } 459ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar 460ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar // Add pass to check for illegal function calls. 461ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar llvm::legacy::PassManager pPM; 462ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar pPM.add(createRSScreenFunctionsPass()); 463ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar pPM.run(module); 464ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar 465ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar return kSuccess; 466ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar 467ebff2ead4ad622ff1bd3f3c108790cead62fe7c7Pirama Arumuga Nainar} 4689e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar 4699e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainarvoid Compiler::translateGEPs(Script &pScript) { 4709e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar llvm::legacy::PassManager pPM; 4719e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar pPM.add(createRSX86TranslateGEPPass()); 4729e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar 4739e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar // Materialization done in screenGlobalFunctions above. 4749e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar pPM.run(pScript.getSource().getModule()); 4759e0f8f0c8965834de02d007bb30e1dc950cf9762Pirama Arumuga Nainar} 476