1 /* 2 * Copyright 2010, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_BACKEND_H_ // NOLINT 18 #define _FRAMEWORKS_COMPILE_SLANG_SLANG_BACKEND_H_ 19 20 #include "clang/AST/ASTConsumer.h" 21 22 #include "llvm/IR/LegacyPassManager.h" 23 24 #include "llvm/Support/raw_ostream.h" 25 26 #include "slang.h" 27 #include "slang_pragma_list.h" 28 #include "slang_rs_check_ast.h" 29 #include "slang_rs_foreach_lowering.h" 30 #include "slang_rs_object_ref_count.h" 31 #include "slang_version.h" 32 33 namespace llvm { 34 class buffer_ostream; 35 class LLVMContext; 36 class NamedMDNode; 37 class Module; 38 } 39 40 namespace clang { 41 class ASTConsumer; 42 class ASTContext; 43 class CodeGenOptions; 44 class CodeGenerator; 45 class DeclGroupRef; 46 class DiagnosticsEngine; 47 class FunctionDecl; 48 class HeaderSearchOptions; 49 class PreprocessorOptions; 50 class TagDecl; 51 class TargetOptions; 52 class VarDecl; 53 } 54 55 namespace slang { 56 57 class RSContext; 58 59 class Backend : public clang::ASTConsumer { 60 private: 61 const clang::TargetOptions &mTargetOpts; 62 63 llvm::Module *mpModule; 64 65 // Output stream 66 llvm::raw_ostream *mpOS; 67 Slang::OutputType mOT; 68 69 // This helps us translate Clang AST using into LLVM IR 70 clang::CodeGenerator *mGen; 71 72 // Passes 73 74 // Passes apply on function scope in a translation unit 75 llvm::legacy::FunctionPassManager *mPerFunctionPasses; 76 // Passes apply on module scope 77 llvm::legacy::PassManager *mPerModulePasses; 78 // Passes for code emission 79 llvm::legacy::FunctionPassManager *mCodeGenPasses; 80 81 llvm::buffer_ostream mBufferOutStream; 82 83 void CreateFunctionPasses(); 84 void CreateModulePasses(); 85 bool CreateCodeGenPasses(); 86 87 RSContext *mContext; 88 89 clang::SourceManager &mSourceMgr; 90 91 bool mASTPrint; 92 93 bool mAllowRSPrefix; 94 95 bool mIsFilterscript; 96 97 llvm::NamedMDNode *mExportVarMetadata; 98 llvm::NamedMDNode *mExportFuncMetadata; 99 llvm::NamedMDNode *mExportForEachNameMetadata; 100 llvm::NamedMDNode *mExportForEachSignatureMetadata; 101 llvm::NamedMDNode *mExportReduceMetadata; 102 llvm::NamedMDNode *mExportTypeMetadata; 103 llvm::NamedMDNode *mRSObjectSlotsMetadata; 104 105 RSObjectRefCount mRefCount; 106 107 RSCheckAST mASTChecker; 108 109 RSForEachLowering mForEachHandler; 110 111 void AnnotateFunction(clang::FunctionDecl *FD); 112 113 void dumpExportVarInfo(llvm::Module *M); 114 void dumpExportFunctionInfo(llvm::Module *M); 115 void dumpExportForEachInfo(llvm::Module *M); 116 void dumpExportReduceInfo(llvm::Module *M); 117 void dumpExportTypeInfo(llvm::Module *M); 118 119 // Translates any rsForEach() or rsForEachWithOptions() calls inside the body 120 // of FD to lower-level runtime calls to rsForEachInternal(), if FD is not a 121 // kernel function itself, as indicated by isKernel being false. If isKernel 122 // is true, reports an error on any calls to rsForEach() or 123 // rsForEachWithOptions(). 124 void LowerRSForEachCall(clang::FunctionDecl* FD, bool isKernel); 125 126 // Insert explicit padding fields into struct to follow the current 127 // layout as defined by the RenderScript ABI (32-bit or 64-bit ARM). 128 // 129 // The padding does not change field offset or structure size -- it 130 // makes explicit any padding that was implicit due to the ABI. 131 // This ensures that if the frontend compiles for an ABI with 132 // stricter alignment requirements than the backend compiles for, 133 // the frontend and backend will still agree on structure layout 134 // (field offset and structure size). This is important for 32-bit 135 // x86: The frontend compiles for 32-bit ARM ABI, in which 64-bit 136 // scalars are 64-bit aligned; but the 32-bit x86 ABI says that 137 // 64-bit scalars are only 32-bit aligned. 138 void PadStruct(clang::RecordDecl* RD); 139 140 protected: 141 llvm::LLVMContext &mLLVMContext; 142 clang::DiagnosticsEngine &mDiagEngine; 143 const clang::CodeGenOptions &mCodeGenOpts; 144 145 PragmaList *mPragmas; 146 getTargetAPI()147 unsigned int getTargetAPI() const { return mContext->getTargetAPI(); } 148 149 // TODO These are no longer virtual from base. Look into merging into caller. 150 151 // This handler will be invoked before Clang translates @Ctx to LLVM IR. This 152 // give you an opportunity to modified the IR in AST level (scope information, 153 // unoptimized IR, etc.). After the return from this method, slang will start 154 // translate @Ctx into LLVM IR. One should not operate on @Ctx afterwards 155 // since the changes applied on that never reflects to the LLVM module used 156 // in the final codegen. 157 void HandleTranslationUnitPre(clang::ASTContext &Ctx); 158 159 // This handler will be invoked when Clang have converted AST tree to LLVM IR. 160 // The @M contains the resulting LLVM IR tree. After the return from this 161 // method, slang will start doing optimization and code generation for @M. 162 void HandleTranslationUnitPost(llvm::Module *M); 163 164 public: 165 Backend(RSContext *Context, 166 clang::DiagnosticsEngine *DiagEngine, 167 const RSCCOptions &Opts, 168 const clang::HeaderSearchOptions &HeaderSearchOpts, 169 const clang::PreprocessorOptions &PreprocessorOpts, 170 const clang::CodeGenOptions &CodeGenOpts, 171 const clang::TargetOptions &TargetOpts, 172 PragmaList *Pragmas, 173 llvm::raw_ostream *OS, 174 Slang::OutputType OT, 175 clang::SourceManager &SourceMgr, 176 bool AllowRSPrefix, 177 bool IsFilterscript); 178 179 virtual ~Backend(); 180 181 // Initialize - This is called to initialize the consumer, providing the 182 // ASTContext. 183 void Initialize(clang::ASTContext &Ctx) override; 184 185 // TODO Clean up what should be private, protected 186 // TODO Also clean up the include files 187 188 // HandleTopLevelDecl - Handle the specified top-level declaration. This is 189 // called by the parser to process every top-level Decl*. Note that D can be 190 // the head of a chain of Decls (e.g. for `int a, b` the chain will have two 191 // elements). Use Decl::getNextDeclarator() to walk the chain. 192 bool HandleTopLevelDecl(clang::DeclGroupRef D) override; 193 194 // HandleTranslationUnit - This method is called when the ASTs for entire 195 // translation unit have been parsed. 196 void HandleTranslationUnit(clang::ASTContext &Ctx) override; 197 198 // HandleTagDeclDefinition - This callback is invoked each time a TagDecl 199 // (e.g. struct, union, enum, class) is completed. This allows the client to 200 // hack on the type, which can occur at any point in the file (because these 201 // can be defined in declspecs). 202 void HandleTagDeclDefinition(clang::TagDecl *D) override; 203 204 // CompleteTentativeDefinition - Callback invoked at the end of a translation 205 // unit to notify the consumer that the given tentative definition should be 206 // completed. 207 void CompleteTentativeDefinition(clang::VarDecl *D) override; 208 }; 209 210 } // namespace slang 211 212 #endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_BACKEND_H_ NOLINT 213