/// \brief Emits the comments that are stored in \p DC comment stream. /// Each comment in the comment stream must end with a newline. static void emitComments(LLVMDisasmContext *DC, formatted_raw_ostream &FormattedOS) { // Flush the stream before taking its content. DC->CommentStream.flush(); StringRef Comments = DC->CommentsToEmit.str(); // Get the default information for printing a comment. const MCAsmInfo *MAI = DC->getAsmInfo(); const char *CommentBegin = MAI->getCommentString(); unsigned CommentColumn = MAI->getCommentColumn(); bool IsFirst = true; while (!Comments.empty()) { if (!IsFirst) FormattedOS << '\n'; // Emit a line of comments. FormattedOS.PadToColumn(CommentColumn); size_t Position = Comments.find('\n'); FormattedOS << CommentBegin << ' ' << Comments.substr(0, Position); // Move after the newline character. Comments = Comments.substr(Position+1); IsFirst = false; } FormattedOS.flush(); // Tell the comment stream that the vector changed underneath it. DC->CommentsToEmit.clear(); DC->CommentStream.resync(); }
static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M, formatted_raw_ostream &OS, LLVMCodeGenFileType codegen, char **ErrorMessage) { TargetMachine* TM = unwrap(T); Module* Mod = unwrap(M); PassManager pass; std::string error; const DataLayout *td = TM->getSubtargetImpl()->getDataLayout(); if (!td) { error = "No DataLayout in TargetMachine"; *ErrorMessage = strdup(error.c_str()); return true; } Mod->setDataLayout(td); pass.add(new DataLayoutPass()); TargetMachine::CodeGenFileType ft; switch (codegen) { case LLVMAssemblyFile: ft = TargetMachine::CGFT_AssemblyFile; break; default: ft = TargetMachine::CGFT_ObjectFile; break; } if (TM->addPassesToEmitFile(pass, OS, ft)) { error = "TargetMachine can't emit a file of this type"; *ErrorMessage = strdup(error.c_str()); return true; } pass.run(*Mod); OS.flush(); return false; }
void PredicateExpander::expandPredicate(formatted_raw_ostream &OS, const Record *Rec) { OS.flush(); unsigned ColNum = getIndentLevel() * 2; if (OS.getColumn() < ColNum) OS.PadToColumn(ColNum); if (Rec->isSubClassOf("MCTrue")) { if (shouldNegate()) return expandFalse(OS); return expandTrue(OS); } if (Rec->isSubClassOf("MCFalse")) { if (shouldNegate()) return expandTrue(OS); return expandFalse(OS); } if (Rec->isSubClassOf("CheckNot")) { flipNegatePredicate(); expandPredicate(OS, Rec->getValueAsDef("Pred")); flipNegatePredicate(); return; } if (Rec->isSubClassOf("CheckIsRegOperand")) return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex")); if (Rec->isSubClassOf("CheckIsImmOperand")) return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex")); if (Rec->isSubClassOf("CheckRegOperand")) return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"), Rec->getValueAsDef("Reg")); if (Rec->isSubClassOf("CheckInvalidRegOperand")) return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex")); if (Rec->isSubClassOf("CheckImmOperand")) return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), Rec->getValueAsInt("ImmVal")); if (Rec->isSubClassOf("CheckImmOperand_s")) return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), Rec->getValueAsString("ImmVal")); if (Rec->isSubClassOf("CheckSameRegOperand")) return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"), Rec->getValueAsInt("SecondIndex")); if (Rec->isSubClassOf("CheckNumOperands")) return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps")); if (Rec->isSubClassOf("CheckPseudo")) return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); if (Rec->isSubClassOf("CheckOpcode")) return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); if (Rec->isSubClassOf("CheckAll")) return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), /* AllOf */ true); if (Rec->isSubClassOf("CheckAny")) return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), /* AllOf */ false); if (Rec->isSubClassOf("CheckFunctionPredicate")) return expandCheckFunctionPredicate( OS, Rec->getValueAsString("MCInstFnName"), Rec->getValueAsString("MachineInstrFnName")); if (Rec->isSubClassOf("CheckNonPortable")) return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock")); if (Rec->isSubClassOf("TIIPredicate")) return expandTIIFunctionCall(OS, Rec->getValueAsString("TargetName"), Rec->getValueAsString("FunctionName")); llvm_unreachable("No known rules to expand this MCInstPredicate"); }
/// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateAssemblyCode(formatted_raw_ostream& out, std::string& errMsg) { if ( this->determineTarget(errMsg) ) return true; // mark which symbols can not be internalized this->applyScopeRestrictions(); Module* mergedModule = _linker.getModule(); // If target supports exception handling then enable it now. switch (_target->getTargetAsmInfo()->getExceptionHandlingType()) { case ExceptionHandling::Dwarf: llvm::DwarfExceptionHandling = true; break; case ExceptionHandling::SjLj: llvm::SjLjExceptionHandling = true; break; case ExceptionHandling::None: break; default: assert (0 && "Unknown exception handling model!"); } // if options were requested, set them if ( !_codegenOptions.empty() ) cl::ParseCommandLineOptions(_codegenOptions.size(), (char**)&_codegenOptions[0]); // Instantiate the pass manager to organize the passes. PassManager passes; // Start off with a verification pass. passes.add(createVerifierPass()); // Add an appropriate TargetData instance for this module... passes.add(new TargetData(*_target->getTargetData())); createStandardLTOPasses(&passes, /*Internalize=*/ false, !DisableInline, /*VerifyEach=*/ false); // Make sure everything is still good. passes.add(createVerifierPass()); FunctionPassManager* codeGenPasses = new FunctionPassManager(new ExistingModuleProvider(mergedModule)); codeGenPasses->add(new TargetData(*_target->getTargetData())); ObjectCodeEmitter* oce = NULL; switch (_target->addPassesToEmitFile(*codeGenPasses, out, TargetMachine::AssemblyFile, CodeGenOpt::Aggressive)) { case FileModel::MachOFile: oce = AddMachOWriter(*codeGenPasses, out, *_target); break; case FileModel::ElfFile: oce = AddELFWriter(*codeGenPasses, out, *_target); break; case FileModel::AsmFile: break; case FileModel::Error: case FileModel::None: errMsg = "target file type not supported"; return true; } if (_target->addPassesToEmitFileFinish(*codeGenPasses, oce, CodeGenOpt::Aggressive)) { errMsg = "target does not support generation of this file type"; return true; } // Run our queue of passes all at once now, efficiently. passes.run(*mergedModule); // Run the code generator, and write assembly file codeGenPasses->doInitialization(); for (Module::iterator it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it) if (!it->isDeclaration()) codeGenPasses->run(*it); codeGenPasses->doFinalization(); out.flush(); return false; // success }