1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // TODO: TargetLibraryInfo is included before sys/... because on Android bionic does #define tricks like: 18 // 19 // #define stat64 stat 20 // #define fstat64 fstat 21 // #define lstat64 lstat 22 // 23 // which causes grief. bionic probably should not do that. 24 #include <llvm/Target/TargetLibraryInfo.h> 25 26 #include "llvm_compilation_unit.h" 27 28 #include <sys/types.h> 29 #include <sys/wait.h> 30 #include <unistd.h> 31 32 #include <string> 33 34 #include <llvm/ADT/OwningPtr.h> 35 #include <llvm/ADT/StringSet.h> 36 #include <llvm/ADT/Triple.h> 37 #include <llvm/Analysis/CallGraph.h> 38 #include <llvm/Analysis/CallGraphSCCPass.h> 39 #include <llvm/Analysis/Dominators.h> 40 #include <llvm/Analysis/LoopInfo.h> 41 #include <llvm/Analysis/LoopPass.h> 42 #include <llvm/Analysis/RegionPass.h> 43 #include <llvm/Analysis/ScalarEvolution.h> 44 #include <llvm/Analysis/Verifier.h> 45 #include <llvm/Assembly/PrintModulePass.h> 46 #include <llvm/Bitcode/ReaderWriter.h> 47 #include <llvm/CodeGen/MachineFrameInfo.h> 48 #include <llvm/CodeGen/MachineFunction.h> 49 #include <llvm/CodeGen/MachineFunctionPass.h> 50 #include <llvm/DebugInfo.h> 51 #include <llvm/IR/DataLayout.h> 52 #include <llvm/IR/DerivedTypes.h> 53 #include <llvm/IR/LLVMContext.h> 54 #include <llvm/IR/Module.h> 55 #include <llvm/Object/ObjectFile.h> 56 #include <llvm/PassManager.h> 57 #include <llvm/Support/Debug.h> 58 #include <llvm/Support/ELF.h> 59 #include <llvm/Support/FormattedStream.h> 60 #include <llvm/Support/ManagedStatic.h> 61 #include <llvm/Support/MemoryBuffer.h> 62 #include <llvm/Support/PassNameParser.h> 63 #include <llvm/Support/PluginLoader.h> 64 #include <llvm/Support/PrettyStackTrace.h> 65 #include <llvm/Support/Signals.h> 66 #include <llvm/Support/SystemUtils.h> 67 #include <llvm/Support/TargetRegistry.h> 68 #include <llvm/Support/TargetSelect.h> 69 #include <llvm/Support/ToolOutputFile.h> 70 #include <llvm/Support/raw_ostream.h> 71 #include <llvm/Support/system_error.h> 72 #include <llvm/Target/TargetMachine.h> 73 #include <llvm/Transforms/IPO.h> 74 #include <llvm/Transforms/IPO/PassManagerBuilder.h> 75 #include <llvm/Transforms/Scalar.h> 76 77 #include "base/logging.h" 78 #include "base/unix_file/fd_file.h" 79 #include "compiled_method.h" 80 #include "compiler_llvm.h" 81 #include "instruction_set.h" 82 #include "ir_builder.h" 83 #include "os.h" 84 #include "runtime_support_builder_arm.h" 85 #include "runtime_support_builder_x86.h" 86 #include "utils_llvm.h" 87 88 namespace art { 89 namespace llvm { 90 91 ::llvm::FunctionPass* 92 CreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb, 93 CompilerDriver* compiler, const DexCompilationUnit* dex_compilation_unit); 94 95 ::llvm::Module* makeLLVMModuleContents(::llvm::Module* module); 96 97 98 LlvmCompilationUnit::LlvmCompilationUnit(const CompilerLLVM* compiler_llvm, size_t cunit_id) 99 : compiler_llvm_(compiler_llvm), cunit_id_(cunit_id) { 100 driver_ = NULL; 101 dex_compilation_unit_ = NULL; 102 llvm_info_.reset(new LLVMInfo()); 103 context_.reset(llvm_info_->GetLLVMContext()); 104 module_ = llvm_info_->GetLLVMModule(); 105 106 // Include the runtime function declaration 107 makeLLVMModuleContents(module_); 108 109 110 intrinsic_helper_.reset(new IntrinsicHelper(*context_, *module_)); 111 112 // Create IRBuilder 113 irb_.reset(new IRBuilder(*context_, *module_, *intrinsic_helper_)); 114 115 // We always need a switch case, so just use a normal function. 116 switch (GetInstructionSet()) { 117 default: 118 runtime_support_.reset(new RuntimeSupportBuilder(*context_, *module_, *irb_)); 119 break; 120 case kThumb2: 121 case kArm: 122 runtime_support_.reset(new RuntimeSupportBuilderARM(*context_, *module_, *irb_)); 123 break; 124 case kX86: 125 runtime_support_.reset(new RuntimeSupportBuilderX86(*context_, *module_, *irb_)); 126 break; 127 } 128 129 irb_->SetRuntimeSupport(runtime_support_.get()); 130 } 131 132 133 LlvmCompilationUnit::~LlvmCompilationUnit() { 134 ::llvm::LLVMContext* llvm_context = context_.release(); // Managed by llvm_info_ 135 CHECK(llvm_context != NULL); 136 } 137 138 139 InstructionSet LlvmCompilationUnit::GetInstructionSet() const { 140 return compiler_llvm_->GetInstructionSet(); 141 } 142 143 144 static std::string DumpDirectory() { 145 if (kIsTargetBuild) { 146 return GetDalvikCacheOrDie("llvm-dump"); 147 } 148 return "/tmp"; 149 } 150 151 void LlvmCompilationUnit::DumpBitcodeToFile() { 152 std::string bitcode; 153 DumpBitcodeToString(bitcode); 154 std::string filename(StringPrintf("%s/Art%zu.bc", DumpDirectory().c_str(), cunit_id_)); 155 std::unique_ptr<File> output(OS::CreateEmptyFile(filename.c_str())); 156 output->WriteFully(bitcode.data(), bitcode.size()); 157 LOG(INFO) << ".bc file written successfully: " << filename; 158 } 159 160 void LlvmCompilationUnit::DumpBitcodeToString(std::string& str_buffer) { 161 ::llvm::raw_string_ostream str_os(str_buffer); 162 ::llvm::WriteBitcodeToFile(module_, str_os); 163 } 164 165 bool LlvmCompilationUnit::Materialize() { 166 const bool kDumpBitcode = false; 167 if (kDumpBitcode) { 168 // Dump the bitcode for debugging 169 DumpBitcodeToFile(); 170 } 171 172 // Compile and prelink ::llvm::Module 173 if (!MaterializeToString(elf_object_)) { 174 LOG(ERROR) << "Failed to materialize compilation unit " << cunit_id_; 175 return false; 176 } 177 178 const bool kDumpELF = false; 179 if (kDumpELF) { 180 // Dump the ELF image for debugging 181 std::string filename(StringPrintf("%s/Art%zu.o", DumpDirectory().c_str(), cunit_id_)); 182 std::unique_ptr<File> output(OS::CreateEmptyFile(filename.c_str())); 183 output->WriteFully(elf_object_.data(), elf_object_.size()); 184 LOG(INFO) << ".o file written successfully: " << filename; 185 } 186 187 return true; 188 } 189 190 191 bool LlvmCompilationUnit::MaterializeToString(std::string& str_buffer) { 192 ::llvm::raw_string_ostream str_os(str_buffer); 193 return MaterializeToRawOStream(str_os); 194 } 195 196 197 bool LlvmCompilationUnit::MaterializeToRawOStream(::llvm::raw_ostream& out_stream) { 198 // Lookup the LLVM target 199 std::string target_triple; 200 std::string target_cpu; 201 std::string target_attr; 202 CompilerDriver::InstructionSetToLLVMTarget(GetInstructionSet(), &target_triple, &target_cpu, 203 &target_attr); 204 205 std::string errmsg; 206 const ::llvm::Target* target = 207 ::llvm::TargetRegistry::lookupTarget(target_triple, errmsg); 208 209 CHECK(target != NULL) << errmsg; 210 211 // Target options 212 ::llvm::TargetOptions target_options; 213 target_options.FloatABIType = ::llvm::FloatABI::Soft; 214 target_options.NoFramePointerElim = true; 215 target_options.UseSoftFloat = false; 216 target_options.EnableFastISel = false; 217 218 // Create the ::llvm::TargetMachine 219 ::llvm::OwningPtr< ::llvm::TargetMachine> target_machine( 220 target->createTargetMachine(target_triple, target_cpu, target_attr, target_options, 221 ::llvm::Reloc::Static, ::llvm::CodeModel::Small, 222 ::llvm::CodeGenOpt::Aggressive)); 223 224 CHECK(target_machine.get() != NULL) << "Failed to create target machine"; 225 226 // Add target data 227 const ::llvm::DataLayout* data_layout = target_machine->getDataLayout(); 228 229 // PassManager for code generation passes 230 ::llvm::PassManager pm; 231 pm.add(new ::llvm::DataLayout(*data_layout)); 232 233 // FunctionPassManager for optimization pass 234 ::llvm::FunctionPassManager fpm(module_); 235 fpm.add(new ::llvm::DataLayout(*data_layout)); 236 237 if (bitcode_filename_.empty()) { 238 // If we don't need write the bitcode to file, add the AddSuspendCheckToLoopLatchPass to the 239 // regular FunctionPass. 240 fpm.add(CreateGBCExpanderPass(*llvm_info_->GetIntrinsicHelper(), *irb_.get(), 241 driver_, dex_compilation_unit_)); 242 } else { 243 ::llvm::FunctionPassManager fpm2(module_); 244 fpm2.add(CreateGBCExpanderPass(*llvm_info_->GetIntrinsicHelper(), *irb_.get(), 245 driver_, dex_compilation_unit_)); 246 fpm2.doInitialization(); 247 for (::llvm::Module::iterator F = module_->begin(), E = module_->end(); 248 F != E; ++F) { 249 fpm2.run(*F); 250 } 251 fpm2.doFinalization(); 252 253 // Write bitcode to file 254 std::string errmsg; 255 256 ::llvm::OwningPtr< ::llvm::tool_output_file> out_file( 257 new ::llvm::tool_output_file(bitcode_filename_.c_str(), errmsg, 258 ::llvm::sys::fs::F_Binary)); 259 260 261 if (!errmsg.empty()) { 262 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg; 263 return false; 264 } 265 266 ::llvm::WriteBitcodeToFile(module_, out_file->os()); 267 out_file->keep(); 268 } 269 270 // Add optimization pass 271 ::llvm::PassManagerBuilder pm_builder; 272 // TODO: Use inliner after we can do IPO. 273 pm_builder.Inliner = NULL; 274 // pm_builder.Inliner = ::llvm::createFunctionInliningPass(); 275 // pm_builder.Inliner = ::llvm::createAlwaysInlinerPass(); 276 // pm_builder.Inliner = ::llvm::createPartialInliningPass(); 277 pm_builder.OptLevel = 3; 278 pm_builder.DisableUnitAtATime = 1; 279 pm_builder.populateFunctionPassManager(fpm); 280 pm_builder.populateModulePassManager(pm); 281 pm.add(::llvm::createStripDeadPrototypesPass()); 282 283 // Add passes to emit ELF image 284 { 285 ::llvm::formatted_raw_ostream formatted_os(out_stream, false); 286 287 // Ask the target to add backend passes as necessary. 288 if (target_machine->addPassesToEmitFile(pm, 289 formatted_os, 290 ::llvm::TargetMachine::CGFT_ObjectFile, 291 true)) { 292 LOG(FATAL) << "Unable to generate ELF for this target"; 293 return false; 294 } 295 296 // Run the per-function optimization 297 fpm.doInitialization(); 298 for (::llvm::Module::iterator F = module_->begin(), E = module_->end(); 299 F != E; ++F) { 300 fpm.run(*F); 301 } 302 fpm.doFinalization(); 303 304 // Run the code generation passes 305 pm.run(*module_); 306 } 307 308 return true; 309 } 310 311 // Check whether the align is less than or equal to the code alignment of 312 // that architecture. Since the Oat writer only guarantee that the compiled 313 // method being aligned to kArchAlignment, we have no way to align the ELf 314 // section if the section alignment is greater than kArchAlignment. 315 void LlvmCompilationUnit::CheckCodeAlign(uint32_t align) const { 316 InstructionSet insn_set = GetInstructionSet(); 317 size_t insn_set_align = GetInstructionSetAlignment(insn_set); 318 CHECK_LE(align, static_cast<uint32_t>(insn_set_align)); 319 } 320 321 322 } // namespace llvm 323 } // namespace art 324