1 //===- opt.cpp - The LLVM Modular Optimizer -------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Optimizations may be specified an arbitrary number of times on the command 11 // line, They are run in the order specified. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "BreakpointPrinter.h" 16 #include "NewPMDriver.h" 17 #include "PassPrinters.h" 18 #include "llvm/ADT/Triple.h" 19 #include "llvm/Analysis/CallGraph.h" 20 #include "llvm/Analysis/CallGraphSCCPass.h" 21 #include "llvm/Analysis/LoopPass.h" 22 #include "llvm/Analysis/RegionPass.h" 23 #include "llvm/Bitcode/BitcodeWriterPass.h" 24 #include "llvm/CodeGen/CommandFlags.h" 25 #include "llvm/IR/DataLayout.h" 26 #include "llvm/IR/IRPrintingPasses.h" 27 #include "llvm/IR/LLVMContext.h" 28 #include "llvm/IR/Module.h" 29 #include "llvm/IR/Verifier.h" 30 #include "llvm/IRReader/IRReader.h" 31 #include "llvm/LinkAllIR.h" 32 #include "llvm/LinkAllPasses.h" 33 #include "llvm/MC/SubtargetFeature.h" 34 #include "llvm/PassManager.h" 35 #include "llvm/Support/Debug.h" 36 #include "llvm/Support/ManagedStatic.h" 37 #include "llvm/Support/PassNameParser.h" 38 #include "llvm/Support/PluginLoader.h" 39 #include "llvm/Support/PrettyStackTrace.h" 40 #include "llvm/Support/Signals.h" 41 #include "llvm/Support/SourceMgr.h" 42 #include "llvm/Support/SystemUtils.h" 43 #include "llvm/Support/TargetRegistry.h" 44 #include "llvm/Support/TargetSelect.h" 45 #include "llvm/Support/ToolOutputFile.h" 46 #include "llvm/Target/TargetLibraryInfo.h" 47 #include "llvm/Target/TargetMachine.h" 48 #include "llvm/Transforms/IPO/PassManagerBuilder.h" 49 #include <algorithm> 50 #include <memory> 51 using namespace llvm; 52 using namespace opt_tool; 53 54 // The OptimizationList is automatically populated with registered Passes by the 55 // PassNameParser. 56 // 57 static cl::list<const PassInfo*, bool, PassNameParser> 58 PassList(cl::desc("Optimizations available:")); 59 60 // This flag specifies a textual description of the optimization pass pipeline 61 // to run over the module. This flag switches opt to use the new pass manager 62 // infrastructure, completely disabling all of the flags specific to the old 63 // pass management. 64 static cl::opt<std::string> PassPipeline( 65 "passes", 66 cl::desc("A textual description of the pass pipeline for optimizing"), 67 cl::Hidden); 68 69 // Other command line options... 70 // 71 static cl::opt<std::string> 72 InputFilename(cl::Positional, cl::desc("<input bitcode file>"), 73 cl::init("-"), cl::value_desc("filename")); 74 75 static cl::opt<std::string> 76 OutputFilename("o", cl::desc("Override output filename"), 77 cl::value_desc("filename")); 78 79 static cl::opt<bool> 80 Force("f", cl::desc("Enable binary output on terminals")); 81 82 static cl::opt<bool> 83 PrintEachXForm("p", cl::desc("Print module after each transformation")); 84 85 static cl::opt<bool> 86 NoOutput("disable-output", 87 cl::desc("Do not write result bitcode file"), cl::Hidden); 88 89 static cl::opt<bool> 90 OutputAssembly("S", cl::desc("Write output as LLVM assembly")); 91 92 static cl::opt<bool> 93 NoVerify("disable-verify", cl::desc("Do not verify result module"), cl::Hidden); 94 95 static cl::opt<bool> 96 VerifyEach("verify-each", cl::desc("Verify after each transform")); 97 98 static cl::opt<bool> 99 StripDebug("strip-debug", 100 cl::desc("Strip debugger symbol info from translation unit")); 101 102 static cl::opt<bool> 103 DisableInline("disable-inlining", cl::desc("Do not run the inliner pass")); 104 105 static cl::opt<bool> 106 DisableOptimizations("disable-opt", 107 cl::desc("Do not run any optimization passes")); 108 109 static cl::opt<bool> 110 DisableInternalize("disable-internalize", 111 cl::desc("Do not mark all symbols as internal")); 112 113 static cl::opt<bool> 114 StandardCompileOpts("std-compile-opts", 115 cl::desc("Include the standard compile time optimizations")); 116 117 static cl::opt<bool> 118 StandardLinkOpts("std-link-opts", 119 cl::desc("Include the standard link time optimizations")); 120 121 static cl::opt<bool> 122 OptLevelO1("O1", 123 cl::desc("Optimization level 1. Similar to clang -O1")); 124 125 static cl::opt<bool> 126 OptLevelO2("O2", 127 cl::desc("Optimization level 2. Similar to clang -O2")); 128 129 static cl::opt<bool> 130 OptLevelOs("Os", 131 cl::desc("Like -O2 with extra optimizations for size. Similar to clang -Os")); 132 133 static cl::opt<bool> 134 OptLevelOz("Oz", 135 cl::desc("Like -Os but reduces code size further. Similar to clang -Oz")); 136 137 static cl::opt<bool> 138 OptLevelO3("O3", 139 cl::desc("Optimization level 3. Similar to clang -O3")); 140 141 static cl::opt<std::string> 142 TargetTriple("mtriple", cl::desc("Override target triple for module")); 143 144 static cl::opt<bool> 145 UnitAtATime("funit-at-a-time", 146 cl::desc("Enable IPO. This is same as llvm-gcc's -funit-at-a-time"), 147 cl::init(true)); 148 149 static cl::opt<bool> 150 DisableLoopUnrolling("disable-loop-unrolling", 151 cl::desc("Disable loop unrolling in all relevant passes"), 152 cl::init(false)); 153 static cl::opt<bool> 154 DisableLoopVectorization("disable-loop-vectorization", 155 cl::desc("Disable the loop vectorization pass"), 156 cl::init(false)); 157 158 static cl::opt<bool> 159 DisableSLPVectorization("disable-slp-vectorization", 160 cl::desc("Disable the slp vectorization pass"), 161 cl::init(false)); 162 163 164 static cl::opt<bool> 165 DisableSimplifyLibCalls("disable-simplify-libcalls", 166 cl::desc("Disable simplify-libcalls")); 167 168 static cl::opt<bool> 169 Quiet("q", cl::desc("Obsolete option"), cl::Hidden); 170 171 static cl::alias 172 QuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet)); 173 174 static cl::opt<bool> 175 AnalyzeOnly("analyze", cl::desc("Only perform analysis, no optimization")); 176 177 static cl::opt<bool> 178 PrintBreakpoints("print-breakpoints-for-testing", 179 cl::desc("Print select breakpoints location for testing")); 180 181 static cl::opt<std::string> 182 DefaultDataLayout("default-data-layout", 183 cl::desc("data layout string to use if not specified by module"), 184 cl::value_desc("layout-string"), cl::init("")); 185 186 187 188 static inline void addPass(PassManagerBase &PM, Pass *P) { 189 // Add the pass to the pass manager... 190 PM.add(P); 191 192 // If we are verifying all of the intermediate steps, add the verifier... 193 if (VerifyEach) PM.add(createVerifierPass()); 194 } 195 196 /// AddOptimizationPasses - This routine adds optimization passes 197 /// based on selected optimization level, OptLevel. This routine 198 /// duplicates llvm-gcc behaviour. 199 /// 200 /// OptLevel - Optimization Level 201 static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, 202 unsigned OptLevel, unsigned SizeLevel) { 203 FPM.add(createVerifierPass()); // Verify that input is correct 204 205 PassManagerBuilder Builder; 206 Builder.OptLevel = OptLevel; 207 Builder.SizeLevel = SizeLevel; 208 209 if (DisableInline) { 210 // No inlining pass 211 } else if (OptLevel > 1) { 212 unsigned Threshold = 225; 213 if (SizeLevel == 1) // -Os 214 Threshold = 75; 215 else if (SizeLevel == 2) // -Oz 216 Threshold = 25; 217 if (OptLevel > 2) 218 Threshold = 275; 219 Builder.Inliner = createFunctionInliningPass(Threshold); 220 } else { 221 Builder.Inliner = createAlwaysInlinerPass(); 222 } 223 Builder.DisableUnitAtATime = !UnitAtATime; 224 Builder.DisableUnrollLoops = (DisableLoopUnrolling.getNumOccurrences() > 0) ? 225 DisableLoopUnrolling : OptLevel == 0; 226 227 // This is final, unless there is a #pragma vectorize enable 228 if (DisableLoopVectorization) 229 Builder.LoopVectorize = false; 230 // If option wasn't forced via cmd line (-vectorize-loops, -loop-vectorize) 231 else if (!Builder.LoopVectorize) 232 Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2; 233 234 // When #pragma vectorize is on for SLP, do the same as above 235 Builder.SLPVectorize = 236 DisableSLPVectorization ? false : OptLevel > 1 && SizeLevel < 2; 237 238 Builder.populateFunctionPassManager(FPM); 239 Builder.populateModulePassManager(MPM); 240 } 241 242 static void AddStandardCompilePasses(PassManagerBase &PM) { 243 PM.add(createVerifierPass()); // Verify that input is correct 244 245 // If the -strip-debug command line option was specified, do it. 246 if (StripDebug) 247 addPass(PM, createStripSymbolsPass(true)); 248 249 if (DisableOptimizations) return; 250 251 // -std-compile-opts adds the same module passes as -O3. 252 PassManagerBuilder Builder; 253 if (!DisableInline) 254 Builder.Inliner = createFunctionInliningPass(); 255 Builder.OptLevel = 3; 256 Builder.populateModulePassManager(PM); 257 } 258 259 static void AddStandardLinkPasses(PassManagerBase &PM) { 260 PM.add(createVerifierPass()); // Verify that input is correct 261 262 // If the -strip-debug command line option was specified, do it. 263 if (StripDebug) 264 addPass(PM, createStripSymbolsPass(true)); 265 266 if (DisableOptimizations) return; 267 268 PassManagerBuilder Builder; 269 Builder.populateLTOPassManager(PM, /*Internalize=*/ !DisableInternalize, 270 /*RunInliner=*/ !DisableInline); 271 } 272 273 //===----------------------------------------------------------------------===// 274 // CodeGen-related helper functions. 275 // 276 static TargetOptions GetTargetOptions() { 277 TargetOptions Options; 278 Options.LessPreciseFPMADOption = EnableFPMAD; 279 Options.NoFramePointerElim = DisableFPElim; 280 Options.AllowFPOpFusion = FuseFPOps; 281 Options.UnsafeFPMath = EnableUnsafeFPMath; 282 Options.NoInfsFPMath = EnableNoInfsFPMath; 283 Options.NoNaNsFPMath = EnableNoNaNsFPMath; 284 Options.HonorSignDependentRoundingFPMathOption = 285 EnableHonorSignDependentRoundingFPMath; 286 Options.UseSoftFloat = GenerateSoftFloatCalls; 287 if (FloatABIForCalls != FloatABI::Default) 288 Options.FloatABIType = FloatABIForCalls; 289 Options.NoZerosInBSS = DontPlaceZerosInBSS; 290 Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; 291 Options.DisableTailCalls = DisableTailCalls; 292 Options.StackAlignmentOverride = OverrideStackAlignment; 293 Options.TrapFuncName = TrapFuncName; 294 Options.PositionIndependentExecutable = EnablePIE; 295 Options.EnableSegmentedStacks = SegmentedStacks; 296 Options.UseInitArray = UseInitArray; 297 return Options; 298 } 299 300 CodeGenOpt::Level GetCodeGenOptLevel() { 301 if (OptLevelO1) 302 return CodeGenOpt::Less; 303 if (OptLevelO2) 304 return CodeGenOpt::Default; 305 if (OptLevelO3) 306 return CodeGenOpt::Aggressive; 307 return CodeGenOpt::None; 308 } 309 310 // Returns the TargetMachine instance or zero if no triple is provided. 311 static TargetMachine* GetTargetMachine(Triple TheTriple) { 312 std::string Error; 313 const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, 314 Error); 315 // Some modules don't specify a triple, and this is okay. 316 if (!TheTarget) { 317 return 0; 318 } 319 320 // Package up features to be passed to target/subtarget 321 std::string FeaturesStr; 322 if (MAttrs.size()) { 323 SubtargetFeatures Features; 324 for (unsigned i = 0; i != MAttrs.size(); ++i) 325 Features.AddFeature(MAttrs[i]); 326 FeaturesStr = Features.getString(); 327 } 328 329 return TheTarget->createTargetMachine(TheTriple.getTriple(), 330 MCPU, FeaturesStr, GetTargetOptions(), 331 RelocModel, CMModel, 332 GetCodeGenOptLevel()); 333 } 334 335 //===----------------------------------------------------------------------===// 336 // main for opt 337 // 338 int main(int argc, char **argv) { 339 sys::PrintStackTraceOnErrorSignal(); 340 llvm::PrettyStackTraceProgram X(argc, argv); 341 342 // Enable debug stream buffering. 343 EnableDebugBuffering = true; 344 345 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 346 LLVMContext &Context = getGlobalContext(); 347 348 InitializeAllTargets(); 349 InitializeAllTargetMCs(); 350 351 // Initialize passes 352 PassRegistry &Registry = *PassRegistry::getPassRegistry(); 353 initializeCore(Registry); 354 initializeDebugIRPass(Registry); 355 initializeScalarOpts(Registry); 356 initializeObjCARCOpts(Registry); 357 initializeVectorization(Registry); 358 initializeIPO(Registry); 359 initializeAnalysis(Registry); 360 initializeIPA(Registry); 361 initializeTransformUtils(Registry); 362 initializeInstCombine(Registry); 363 initializeInstrumentation(Registry); 364 initializeTarget(Registry); 365 366 cl::ParseCommandLineOptions(argc, argv, 367 "llvm .bc -> .bc modular optimizer and analysis printer\n"); 368 369 if (AnalyzeOnly && NoOutput) { 370 errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n"; 371 return 1; 372 } 373 374 SMDiagnostic Err; 375 376 // Load the input module... 377 OwningPtr<Module> M; 378 M.reset(ParseIRFile(InputFilename, Err, Context)); 379 380 if (M.get() == 0) { 381 Err.print(argv[0], errs()); 382 return 1; 383 } 384 385 // If we are supposed to override the target triple, do so now. 386 if (!TargetTriple.empty()) 387 M->setTargetTriple(Triple::normalize(TargetTriple)); 388 389 // Figure out what stream we are supposed to write to... 390 OwningPtr<tool_output_file> Out; 391 if (NoOutput) { 392 if (!OutputFilename.empty()) 393 errs() << "WARNING: The -o (output filename) option is ignored when\n" 394 "the --disable-output option is used.\n"; 395 } else { 396 // Default to standard output. 397 if (OutputFilename.empty()) 398 OutputFilename = "-"; 399 400 std::string ErrorInfo; 401 Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, 402 sys::fs::F_Binary)); 403 if (!ErrorInfo.empty()) { 404 errs() << ErrorInfo << '\n'; 405 return 1; 406 } 407 } 408 409 // If the output is set to be emitted to standard out, and standard out is a 410 // console, print out a warning message and refuse to do it. We don't 411 // impress anyone by spewing tons of binary goo to a terminal. 412 if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly) 413 if (CheckBitcodeOutputToConsole(Out->os(), !Quiet)) 414 NoOutput = true; 415 416 if (PassPipeline.getNumOccurrences() > 0) { 417 OutputKind OK = OK_NoOutput; 418 if (!NoOutput) 419 OK = OutputAssembly ? OK_OutputAssembly : OK_OutputBitcode; 420 421 VerifierKind VK = VK_VerifyInAndOut; 422 if (NoVerify) 423 VK = VK_NoVerifier; 424 else if (VerifyEach) 425 VK = VK_VerifyEachPass; 426 427 // The user has asked to use the new pass manager and provided a pipeline 428 // string. Hand off the rest of the functionality to the new code for that 429 // layer. 430 return runPassPipeline(argv[0], Context, *M.get(), Out.get(), PassPipeline, 431 OK, VK) 432 ? 0 433 : 1; 434 } 435 436 // Create a PassManager to hold and optimize the collection of passes we are 437 // about to build. 438 // 439 PassManager Passes; 440 441 // Add an appropriate TargetLibraryInfo pass for the module's triple. 442 TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple())); 443 444 // The -disable-simplify-libcalls flag actually disables all builtin optzns. 445 if (DisableSimplifyLibCalls) 446 TLI->disableAllFunctions(); 447 Passes.add(TLI); 448 449 // Add an appropriate DataLayout instance for this module. 450 DataLayout *TD = 0; 451 const std::string &ModuleDataLayout = M.get()->getDataLayout(); 452 if (!ModuleDataLayout.empty()) 453 TD = new DataLayout(ModuleDataLayout); 454 else if (!DefaultDataLayout.empty()) 455 TD = new DataLayout(DefaultDataLayout); 456 457 if (TD) 458 Passes.add(TD); 459 460 Triple ModuleTriple(M->getTargetTriple()); 461 TargetMachine *Machine = 0; 462 if (ModuleTriple.getArch()) 463 Machine = GetTargetMachine(Triple(ModuleTriple)); 464 OwningPtr<TargetMachine> TM(Machine); 465 466 // Add internal analysis passes from the target machine. 467 if (TM.get()) 468 TM->addAnalysisPasses(Passes); 469 470 OwningPtr<FunctionPassManager> FPasses; 471 if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { 472 FPasses.reset(new FunctionPassManager(M.get())); 473 if (TD) 474 FPasses->add(new DataLayout(*TD)); 475 if (TM.get()) 476 TM->addAnalysisPasses(*FPasses); 477 478 } 479 480 if (PrintBreakpoints) { 481 // Default to standard output. 482 if (!Out) { 483 if (OutputFilename.empty()) 484 OutputFilename = "-"; 485 486 std::string ErrorInfo; 487 Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, 488 sys::fs::F_Binary)); 489 if (!ErrorInfo.empty()) { 490 errs() << ErrorInfo << '\n'; 491 return 1; 492 } 493 } 494 Passes.add(createBreakpointPrinter(Out->os())); 495 NoOutput = true; 496 } 497 498 // If the -strip-debug command line option was specified, add it. If 499 // -std-compile-opts was also specified, it will handle StripDebug. 500 if (StripDebug && !StandardCompileOpts) 501 addPass(Passes, createStripSymbolsPass(true)); 502 503 // Create a new optimization pass for each one specified on the command line 504 for (unsigned i = 0; i < PassList.size(); ++i) { 505 // Check to see if -std-compile-opts was specified before this option. If 506 // so, handle it. 507 if (StandardCompileOpts && 508 StandardCompileOpts.getPosition() < PassList.getPosition(i)) { 509 AddStandardCompilePasses(Passes); 510 StandardCompileOpts = false; 511 } 512 513 if (StandardLinkOpts && 514 StandardLinkOpts.getPosition() < PassList.getPosition(i)) { 515 AddStandardLinkPasses(Passes); 516 StandardLinkOpts = false; 517 } 518 519 if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { 520 AddOptimizationPasses(Passes, *FPasses, 1, 0); 521 OptLevelO1 = false; 522 } 523 524 if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { 525 AddOptimizationPasses(Passes, *FPasses, 2, 0); 526 OptLevelO2 = false; 527 } 528 529 if (OptLevelOs && OptLevelOs.getPosition() < PassList.getPosition(i)) { 530 AddOptimizationPasses(Passes, *FPasses, 2, 1); 531 OptLevelOs = false; 532 } 533 534 if (OptLevelOz && OptLevelOz.getPosition() < PassList.getPosition(i)) { 535 AddOptimizationPasses(Passes, *FPasses, 2, 2); 536 OptLevelOz = false; 537 } 538 539 if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { 540 AddOptimizationPasses(Passes, *FPasses, 3, 0); 541 OptLevelO3 = false; 542 } 543 544 const PassInfo *PassInf = PassList[i]; 545 Pass *P = 0; 546 if (PassInf->getTargetMachineCtor()) 547 P = PassInf->getTargetMachineCtor()(TM.get()); 548 else if (PassInf->getNormalCtor()) 549 P = PassInf->getNormalCtor()(); 550 else 551 errs() << argv[0] << ": cannot create pass: " 552 << PassInf->getPassName() << "\n"; 553 if (P) { 554 PassKind Kind = P->getPassKind(); 555 addPass(Passes, P); 556 557 if (AnalyzeOnly) { 558 switch (Kind) { 559 case PT_BasicBlock: 560 Passes.add(createBasicBlockPassPrinter(PassInf, Out->os(), Quiet)); 561 break; 562 case PT_Region: 563 Passes.add(createRegionPassPrinter(PassInf, Out->os(), Quiet)); 564 break; 565 case PT_Loop: 566 Passes.add(createLoopPassPrinter(PassInf, Out->os(), Quiet)); 567 break; 568 case PT_Function: 569 Passes.add(createFunctionPassPrinter(PassInf, Out->os(), Quiet)); 570 break; 571 case PT_CallGraphSCC: 572 Passes.add(createCallGraphPassPrinter(PassInf, Out->os(), Quiet)); 573 break; 574 default: 575 Passes.add(createModulePassPrinter(PassInf, Out->os(), Quiet)); 576 break; 577 } 578 } 579 } 580 581 if (PrintEachXForm) 582 Passes.add(createPrintModulePass(errs())); 583 } 584 585 // If -std-compile-opts was specified at the end of the pass list, add them. 586 if (StandardCompileOpts) { 587 AddStandardCompilePasses(Passes); 588 StandardCompileOpts = false; 589 } 590 591 if (StandardLinkOpts) { 592 AddStandardLinkPasses(Passes); 593 StandardLinkOpts = false; 594 } 595 596 if (OptLevelO1) 597 AddOptimizationPasses(Passes, *FPasses, 1, 0); 598 599 if (OptLevelO2) 600 AddOptimizationPasses(Passes, *FPasses, 2, 0); 601 602 if (OptLevelOs) 603 AddOptimizationPasses(Passes, *FPasses, 2, 1); 604 605 if (OptLevelOz) 606 AddOptimizationPasses(Passes, *FPasses, 2, 2); 607 608 if (OptLevelO3) 609 AddOptimizationPasses(Passes, *FPasses, 3, 0); 610 611 if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { 612 FPasses->doInitialization(); 613 for (Module::iterator F = M->begin(), E = M->end(); F != E; ++F) 614 FPasses->run(*F); 615 FPasses->doFinalization(); 616 } 617 618 // Check that the module is well formed on completion of optimization 619 if (!NoVerify && !VerifyEach) 620 Passes.add(createVerifierPass()); 621 622 // Write bitcode or assembly to the output as the last step... 623 if (!NoOutput && !AnalyzeOnly) { 624 if (OutputAssembly) 625 Passes.add(createPrintModulePass(Out->os())); 626 else 627 Passes.add(createBitcodeWriterPass(Out->os())); 628 } 629 630 // Before executing passes, print the final values of the LLVM options. 631 cl::PrintOptionValues(); 632 633 // Now that we have all of the passes ready, run them. 634 Passes.run(*M.get()); 635 636 // Declare success. 637 if (!NoOutput || PrintBreakpoints) 638 Out->keep(); 639 640 return 0; 641 } 642