14a10645c70199c8d8567fbc46312158c419720abChris Lattner//===- Miscompilation.cpp - Debug program miscompilations -----------------===// 23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// The LLVM Compiler Infrastructure 47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// 521c62da287237d39d0d95004881ea4baae3be6daChris Lattner// This file is distributed under the University of Illinois Open Source 621c62da287237d39d0d95004881ea4baae3be6daChris Lattner// License. See LICENSE.TXT for details. 73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//===----------------------------------------------------------------------===// 94a10645c70199c8d8567fbc46312158c419720abChris Lattner// 10a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner// This file implements optimizer and code generation miscompilation debugging 11a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner// support. 124a10645c70199c8d8567fbc46312158c419720abChris Lattner// 134a10645c70199c8d8567fbc46312158c419720abChris Lattner//===----------------------------------------------------------------------===// 144a10645c70199c8d8567fbc46312158c419720abChris Lattner 154a10645c70199c8d8567fbc46312158c419720abChris Lattner#include "BugDriver.h" 16126840f49e8d49156a342e836d4b2adca46dc3baChris Lattner#include "ListReducer.h" 17ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar#include "ToolRunner.h" 18f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Analysis/Verifier.h" 19f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Config/config.h" // for HAVE_LINK_R 200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h" 230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 24605b9e2c5bd1b0c151a0b15d01e6df3aba93d52fReid Spencer#include "llvm/Linker.h" 25e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Pass.h" 26551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h" 27551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/FileUtilities.h" 28f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Transforms/Utils/Cloning.h" 29fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattnerusing namespace llvm; 304a10645c70199c8d8567fbc46312158c419720abChris Lattner 31a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattnernamespace llvm { 3268ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar extern cl::opt<std::string> OutputPrefix; 33a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner extern cl::list<std::string> InputArgv; 34a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner} 35a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 36efdc0b505712d1ca4460def27e51c430f033d58dChris Lattnernamespace { 3756584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer static llvm::cl::opt<bool> 3856584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer DisableLoopExtraction("disable-loop-extraction", 39dc31a8a70cab3b4c180ac1a482855e31d3fe8e6bReid Spencer cl::desc("Don't extract loops when searching for miscompilations"), 40dc31a8a70cab3b4c180ac1a482855e31d3fe8e6bReid Spencer cl::init(false)); 4156584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer static llvm::cl::opt<bool> 4256584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer DisableBlockExtraction("disable-block-extraction", 43265d82e4c68fa30b7ff1cb650456249f7068bdd6David Goodwin cl::desc("Don't extract blocks when searching for miscompilations"), 44265d82e4c68fa30b7ff1cb650456249f7068bdd6David Goodwin cl::init(false)); 45dc31a8a70cab3b4c180ac1a482855e31d3fe8e6bReid Spencer 468261dfed05e32302469ef707cc881fed2c31f85fRafael Espindola class ReduceMiscompilingPasses : public ListReducer<std::string> { 47fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner BugDriver &BD; 48fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner public: 49fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {} 503da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 518261dfed05e32302469ef707cc881fed2c31f85fRafael Espindola virtual TestResult doTest(std::vector<std::string> &Prefix, 528261dfed05e32302469ef707cc881fed2c31f85fRafael Espindola std::vector<std::string> &Suffix, 5322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &Error); 54fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner }; 55fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner} 56640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 578c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// TestResult - After passes have been split into a test group and a control 588c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// group, see if they still break the program. 598c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// 60640f22e66d90439857a97a83896ee68c4f7128c9Chris LattnerReduceMiscompilingPasses::TestResult 618261dfed05e32302469ef707cc881fed2c31f85fRafael EspindolaReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix, 628261dfed05e32302469ef707cc881fed2c31f85fRafael Espindola std::vector<std::string> &Suffix, 6322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &Error) { 6406943add8b2b764e131979cca064eda9f28826c9Chris Lattner // First, run the program with just the Suffix passes. If it is still broken 65640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // with JUST the kept passes, discard the prefix passes. 66ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Checking to see if '" << getPassesString(Suffix) 67ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman << "' compiles correctly: "; 68640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 698ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif std::string BitcodeResult; 70ca356afe09454b3378165ded4eda294bd6341428Rafael Espindola if (BD.runPasses(BD.getProgram(), Suffix, BitcodeResult, false/*delete*/, 71ca356afe09454b3378165ded4eda294bd6341428Rafael Espindola true/*quiet*/)) { 7265f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << " Error running this sequence of passes" 7365f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman << " on the input program!\n"; 745ef681c19de9c675a265211f8fb0ae49cc3a3a66Chris Lattner BD.setPassesToRun(Suffix); 75bae1b71cbb930e419df03db209ebc547a0e4ec72Rafael Espindola BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); 76025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner exit(BD.debugOptimizerCrash()); 77640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner } 7856584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer 79640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // Check to see if the finished program matches the reference output... 8010757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola bool Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", 8110757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola true /*delete bitcode*/, &Error); 8222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 8322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return InternalError; 8422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Diff) { 85ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " nope.\n"; 8659615f0f85e2ac99e012cb81934d002faebd405aChris Lattner if (Suffix.empty()) { 8765f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << BD.getToolName() << ": I'm confused: the test fails when " 8865f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman << "no passes are run, nondeterministic program?\n"; 8959615f0f85e2ac99e012cb81934d002faebd405aChris Lattner exit(1); 9059615f0f85e2ac99e012cb81934d002faebd405aChris Lattner } 91123f8fec94d1f22d876382897231868c62f8eabbMisha Brukman return KeepSuffix; // Miscompilation detected! 92640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner } 93ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " yup.\n"; // No miscompilation! 94640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 95640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner if (Prefix.empty()) return NoFailure; 96640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 9706943add8b2b764e131979cca064eda9f28826c9Chris Lattner // Next, see if the program is broken if we run the "prefix" passes first, 98bc0e998c497446f5448425b3cbd7f8f19a458764Misha Brukman // then separately run the "kept" passes. 99ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Checking to see if '" << getPassesString(Prefix) 100ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman << "' compiles correctly: "; 101640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 102640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // If it is not broken with the kept passes, it's possible that the prefix 103640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // passes must be run before the kept passes to break it. If the program 104640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // WORKS after the prefix passes, but then fails if running the prefix AND 1058ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif // kept passes, we can update our bitcode file to include the result of the 106640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // prefix passes, then discard the prefix passes. 107640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // 108ca356afe09454b3378165ded4eda294bd6341428Rafael Espindola if (BD.runPasses(BD.getProgram(), Prefix, BitcodeResult, false/*delete*/, 109ca356afe09454b3378165ded4eda294bd6341428Rafael Espindola true/*quiet*/)) { 11065f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << " Error running this sequence of passes" 11165f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman << " on the input program!\n"; 1129c6cfe1bffd37f29a265457b7515839c445b3e6aChris Lattner BD.setPassesToRun(Prefix); 113bae1b71cbb930e419df03db209ebc547a0e4ec72Rafael Espindola BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); 114025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner exit(BD.debugOptimizerCrash()); 115640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner } 116640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 117640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // If the prefix maintains the predicate by itself, only keep the prefix! 11810757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", false, &Error); 11922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 12022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return InternalError; 12122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Diff) { 122ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " nope.\n"; 12374aec35172e3278a57b474d0dec5d81302af932cRafael Espindola sys::fs::remove(BitcodeResult); 124640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner return KeepPrefix; 125640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner } 126ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " yup.\n"; // No miscompilation! 127640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 128640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // Ok, so now we know that the prefix passes work, try running the suffix 129640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // passes on the result of the prefix passes. 130640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // 1316865f29fe71559a18d7f2ff0bc4f67c5fc1d000eJeffrey Yasskin OwningPtr<Module> PrefixOutput(ParseInputFile(BitcodeResult, 1326865f29fe71559a18d7f2ff0bc4f67c5fc1d000eJeffrey Yasskin BD.getContext())); 133453f4f01302f00651aae2fc7658f6e23a2beadb0David Blaikie if (!PrefixOutput) { 13465f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << BD.getToolName() << ": Error reading bitcode file '" 13565f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman << BitcodeResult << "'!\n"; 136640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner exit(1); 137640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner } 13874aec35172e3278a57b474d0dec5d81302af932cRafael Espindola sys::fs::remove(BitcodeResult); 139f4789e6d04c1fddb40092a1193c4a5eb67387accChris Lattner 140f4789e6d04c1fddb40092a1193c4a5eb67387accChris Lattner // Don't check if there are no passes in the suffix. 141f4789e6d04c1fddb40092a1193c4a5eb67387accChris Lattner if (Suffix.empty()) 142f4789e6d04c1fddb40092a1193c4a5eb67387accChris Lattner return NoFailure; 1433da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 144ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Checking to see if '" << getPassesString(Suffix) 145640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner << "' passes compile correctly after the '" 146640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner << getPassesString(Prefix) << "' passes: "; 147640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 1486865f29fe71559a18d7f2ff0bc4f67c5fc1d000eJeffrey Yasskin OwningPtr<Module> OriginalInput(BD.swapProgramIn(PrefixOutput.take())); 149ca356afe09454b3378165ded4eda294bd6341428Rafael Espindola if (BD.runPasses(BD.getProgram(), Suffix, BitcodeResult, false/*delete*/, 150ca356afe09454b3378165ded4eda294bd6341428Rafael Espindola true/*quiet*/)) { 15165f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << " Error running this sequence of passes" 15265f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman << " on the input program!\n"; 1535ef681c19de9c675a265211f8fb0ae49cc3a3a66Chris Lattner BD.setPassesToRun(Suffix); 154bae1b71cbb930e419df03db209ebc547a0e4ec72Rafael Espindola BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); 155025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner exit(BD.debugOptimizerCrash()); 156640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner } 157640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 158640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // Run the result... 15910757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", 16010757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola true /*delete bitcode*/, &Error); 16122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 16222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return InternalError; 16322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Diff) { 164ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " nope.\n"; 16506943add8b2b764e131979cca064eda9f28826c9Chris Lattner return KeepSuffix; 166640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner } 167640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 168640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // Otherwise, we must not be running the bad pass anymore. 169ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " yup.\n"; // No miscompilation! 1706865f29fe71559a18d7f2ff0bc4f67c5fc1d000eJeffrey Yasskin // Restore orig program & free test. 1716865f29fe71559a18d7f2ff0bc4f67c5fc1d000eJeffrey Yasskin delete BD.swapProgramIn(OriginalInput.take()); 172640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner return NoFailure; 173640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner} 174640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 175efdc0b505712d1ca4460def27e51c430f033d58dChris Lattnernamespace { 176fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner class ReduceMiscompilingFunctions : public ListReducer<Function*> { 177fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner BugDriver &BD; 17822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool (*TestFn)(BugDriver &, Module *, Module *, std::string &); 179fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner public: 180b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner ReduceMiscompilingFunctions(BugDriver &bd, 18122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool (*F)(BugDriver &, Module *, Module *, 18222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &)) 183b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner : BD(bd), TestFn(F) {} 1843da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 185fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner virtual TestResult doTest(std::vector<Function*> &Prefix, 18622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::vector<Function*> &Suffix, 18722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &Error) { 18822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Suffix.empty()) { 18922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool Ret = TestFuncs(Suffix, Error); 19022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 19122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return InternalError; 19222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Ret) 19322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return KeepSuffix; 19422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky } 19522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Prefix.empty()) { 19622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool Ret = TestFuncs(Prefix, Error); 19722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 19822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return InternalError; 19922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Ret) 20022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return KeepPrefix; 20122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky } 202fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner return NoFailure; 203fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner } 2043da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 20584ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola bool TestFuncs(const std::vector<Function*> &Prefix, std::string &Error); 206fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner }; 207fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner} 208640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 209efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner/// TestMergedProgram - Given two modules, link them together and run the 21013793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola/// program, checking to see if the program matches the diff. If there is 21113793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola/// an error, return NULL. If not, return the merged module. The Broken argument 21213793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola/// will be set to true if the output is different. If the DeleteInputs 21313793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola/// argument is set to true then this function deletes both input 21413793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola/// modules before it returns. 2158c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// 21613793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindolastatic Module *TestMergedProgram(const BugDriver &BD, Module *M1, Module *M2, 21713793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola bool DeleteInputs, std::string &Error, 21813793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola bool &Broken) { 219efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner // Link the two portions of the program back to together. 220efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner std::string ErrorMsg; 22190c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner if (!DeleteInputs) { 22290c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner M1 = CloneModule(M1); 22390c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner M2 = CloneModule(M2); 22490c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner } 225f1f1a4f16128ffa2910f0b1d5c7052b3697f9fcdTanya Lattner if (Linker::LinkModules(M1, M2, Linker::DestroySource, &ErrorMsg)) { 22665f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << BD.getToolName() << ": Error linking modules together:" 22765f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman << ErrorMsg << '\n'; 228efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner exit(1); 229efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner } 23090c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner delete M2; // We are done with this module. 231efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner 23213793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola // Execute the program. 23313793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola Broken = BD.diffProgram(M1, "", "", false, &Error); 23422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) { 23510757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola // Delete the linked module 23610757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola delete M1; 23713793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola return NULL; 23822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky } 23913793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola return M1; 240efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner} 241efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner 2428c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// TestFuncs - split functions in a Module into two groups: those that are 2438c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// under consideration for miscompilation vs. those that are not, and test 2448c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// accordingly. Each group of functions becomes a separate Module. 2458c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// 24684ae206c976c76761e307e5c45f8170d0b61015fRafael Espindolabool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs, 24784ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola std::string &Error) { 248640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // Test to see if the function is misoptimized if we ONLY run it on the 249640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // functions listed in Funcs. 250ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Checking to see if the program is misoptimized when " 251ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman << (Funcs.size()==1 ? "this function is" : "these functions are") 252ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman << " run through the pass" 253ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman << (BD.getPassesToRun().size() == 1 ? "" : "es") << ":"; 254efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner PrintFunctionList(Funcs); 255ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << '\n'; 256640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 25784ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola // Create a clone for two reasons: 25884ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola // * If the optimization passes delete any function, the deleted function 25984ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola // will be in the clone and Funcs will still point to valid memory 26084ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola // * If the optimization passes use interprocedural information to break 26184ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola // a function, we want to continue with the original function. Otherwise 26284ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola // we can conclude that a function triggers the bug when in fact one 26384ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola // needs a larger set of original functions to do so. 2641ed219a9d2279ce5a5bbcf16d9b7ccc05cce638cRafael Espindola ValueToValueMapTy VMap; 26584ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola Module *Clone = CloneModule(BD.getProgram(), VMap); 26684ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola Module *Orig = BD.swapProgramIn(Clone); 26784ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola 26884ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola std::vector<Function*> FuncsOnClone; 26984ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { 27084ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola Function *F = cast<Function>(VMap[Funcs[i]]); 27184ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola FuncsOnClone.push_back(F); 27284ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola } 27384ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola 27484ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola // Split the module into the two halves of the program we want. 27584ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola VMap.clear(); 276e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap); 27784ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, FuncsOnClone, 278e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel VMap); 279640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 2806fa98b13206583e6eb90b8304758b35548914944Nick Lewycky // Run the predicate, note that the predicate will delete both input modules. 28184ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola bool Broken = TestFn(BD, ToOptimize, ToNotOptimize, Error); 28284ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola 28384ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola delete BD.swapProgramIn(Orig); 28484ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola 28584ae206c976c76761e307e5c45f8170d0b61015fRafael Espindola return Broken; 286640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner} 287640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 2888abfb8adb2f383cab46a5e8b9fca4301effd8140Chris Lattner/// DisambiguateGlobalSymbols - Give anonymous global values names. 2898c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// 29036ee07ff9d26a2c6ebf9faf9ba90923644db29c5Chris Lattnerstatic void DisambiguateGlobalSymbols(Module *M) { 29167ef9e43049c28c8fe2c9f70d2ad163045ee5876Chris Lattner for (Module::global_iterator I = M->global_begin(), E = M->global_end(); 2921ffb33d033d3593ded0adb08b05eb455cce59ea8Chris Lattner I != E; ++I) 2938abfb8adb2f383cab46a5e8b9fca4301effd8140Chris Lattner if (!I->hasName()) 2948abfb8adb2f383cab46a5e8b9fca4301effd8140Chris Lattner I->setName("anon_global"); 2951ffb33d033d3593ded0adb08b05eb455cce59ea8Chris Lattner for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) 2968abfb8adb2f383cab46a5e8b9fca4301effd8140Chris Lattner if (!I->hasName()) 2978abfb8adb2f383cab46a5e8b9fca4301effd8140Chris Lattner I->setName("anon_fn"); 29836ee07ff9d26a2c6ebf9faf9ba90923644db29c5Chris Lattner} 29936ee07ff9d26a2c6ebf9faf9ba90923644db29c5Chris Lattner 300a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner/// ExtractLoops - Given a reduced list of functions that still exposed the bug, 301a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner/// check to see if we can extract the loops in the region without obscuring the 302a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner/// bug. If so, it reduces the amount of code identified. 3038c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// 304b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattnerstatic bool ExtractLoops(BugDriver &BD, 30522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool (*TestFn)(BugDriver &, Module *, Module *, 30622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &), 30722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::vector<Function*> &MiscompiledFunctions, 30822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &Error) { 309a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner bool MadeChange = false; 310a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner while (1) { 311aed98fa8861a28e5f7ba7c0659e106f2a441e9ffChris Lattner if (BugpointIsInterrupted) return MadeChange; 31256584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer 3131ed219a9d2279ce5a5bbcf16d9b7ccc05cce638cRafael Espindola ValueToValueMapTy VMap; 314e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap); 315a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, 316d50330cd02b00c8e3de40e8544c45701b9891d87Dan Gohman MiscompiledFunctions, 317e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel VMap); 318a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner Module *ToOptimizeLoopExtracted = BD.ExtractLoop(ToOptimize); 319a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner if (!ToOptimizeLoopExtracted) { 320a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // If the loop extractor crashed or if there were no extractible loops, 321a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // then this chapter of our odyssey is over with. 322a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner delete ToNotOptimize; 323a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner delete ToOptimize; 324a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner return MadeChange; 325a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner } 326a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner 32765f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << "Extracted a loop from the breaking portion of the program.\n"; 328a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner 329a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // Bugpoint is intentionally not very trusting of LLVM transformations. In 330a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // particular, we're not going to assume that the loop extractor works, so 331a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // we're going to test the newly loop extracted program to make sure nothing 332a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // has broken. If something broke, then we'll inform the user and stop 333a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // extraction. 33470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman AbstractInterpreter *AI = BD.switchToSafeInterpreter(); 33513793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola bool Failure; 33613793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola Module *New = TestMergedProgram(BD, ToOptimizeLoopExtracted, ToNotOptimize, 33713793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola false, Error, Failure); 33813793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola if (!New) 33922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return false; 340e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel 34113793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola // Delete the original and set the new program. 342e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel Module *Old = BD.swapProgramIn(New); 343e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) 344e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]); 345e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel delete Old; 346e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel 34722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Failure) { 348a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner BD.switchToInterpreter(AI); 349a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 350a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // Merged program doesn't work anymore! 35165f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << " *** ERROR: Loop extraction broke the program. :(" 35265f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman << " Please report a bug!\n"; 35365f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << " Continuing on with un-loop-extracted version.\n"; 35456c418676a308034e5eecf10d3f96ced2d1fab24Chris Lattner 35568ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-tno.bc", 35668ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar ToNotOptimize); 35768ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to.bc", 35868ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar ToOptimize); 35968ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to-le.bc", 36056c418676a308034e5eecf10d3f96ced2d1fab24Chris Lattner ToOptimizeLoopExtracted); 36156c418676a308034e5eecf10d3f96ced2d1fab24Chris Lattner 36256584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer errs() << "Please submit the " 36368ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar << OutputPrefix << "-loop-extract-fail-*.bc files.\n"; 36456c418676a308034e5eecf10d3f96ced2d1fab24Chris Lattner delete ToOptimize; 365a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner delete ToNotOptimize; 366a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner delete ToOptimizeLoopExtracted; 367a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner return MadeChange; 368a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner } 36956c418676a308034e5eecf10d3f96ced2d1fab24Chris Lattner delete ToOptimize; 370a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner BD.switchToInterpreter(AI); 3713da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 372ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " Testing after loop extraction:\n"; 373b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner // Clone modules, the tester function will free them. 374e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel Module *TOLEBackup = CloneModule(ToOptimizeLoopExtracted, VMap); 375e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel Module *TNOBackup = CloneModule(ToNotOptimize, VMap); 376e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel 377e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) 378e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]); 379e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel 38022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky Failure = TestFn(BD, ToOptimizeLoopExtracted, ToNotOptimize, Error); 38122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 38222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return false; 383e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel 384e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel ToOptimizeLoopExtracted = TOLEBackup; 385e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel ToNotOptimize = TNOBackup; 386e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel 38722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Failure) { 388ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "*** Loop extraction masked the problem. Undoing.\n"; 389a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // If the program is not still broken, then loop extraction did something 390a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // that masked the error. Stop loop extraction now. 391e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel 392e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel std::vector<std::pair<std::string, FunctionType*> > MisCompFunctions; 393e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) { 394e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel Function *F = MiscompiledFunctions[i]; 395e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel MisCompFunctions.push_back(std::make_pair(F->getName(), 396e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel F->getFunctionType())); 397e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel } 398e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel 399e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel std::string ErrorMsg; 400e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted, 401e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel Linker::DestroySource, &ErrorMsg)){ 402e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel errs() << BD.getToolName() << ": Error linking modules together:" 403e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel << ErrorMsg << '\n'; 404e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel exit(1); 405e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel } 406e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel 407e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel MiscompiledFunctions.clear(); 408e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { 409e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first); 410e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel 411e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel assert(NewF && "Function not found??"); 412e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel MiscompiledFunctions.push_back(NewF); 413e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel } 414e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel 415e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel delete ToOptimizeLoopExtracted; 416e8bc700a87b88751b82e132b10c4b96f311e0b3aHal Finkel BD.setNewProgram(ToNotOptimize); 417a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner return MadeChange; 418a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner } 419b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner 420ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "*** Loop extraction successful!\n"; 421a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner 422db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner std::vector<std::pair<std::string, FunctionType*> > MisCompFunctions; 42390c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner for (Module::iterator I = ToOptimizeLoopExtracted->begin(), 42490c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner E = ToOptimizeLoopExtracted->end(); I != E; ++I) 4255cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer if (!I->isDeclaration()) 426fa1af1344910ee975f50ffdddf605c26f80ef016Chris Lattner MisCompFunctions.push_back(std::make_pair(I->getName(), 427fa1af1344910ee975f50ffdddf605c26f80ef016Chris Lattner I->getFunctionType())); 42890c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner 429a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // Okay, great! Now we know that we extracted a loop and that loop 430a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // extraction both didn't break the program, and didn't mask the problem. 431a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // Replace the current program with the loop extracted version, and try to 432a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // extract another loop. 433a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner std::string ErrorMsg; 434f1f1a4f16128ffa2910f0b1d5c7052b3697f9fcdTanya Lattner if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted, 435f1f1a4f16128ffa2910f0b1d5c7052b3697f9fcdTanya Lattner Linker::DestroySource, &ErrorMsg)){ 43665f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << BD.getToolName() << ": Error linking modules together:" 43765f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman << ErrorMsg << '\n'; 438a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner exit(1); 439a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner } 44090c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner delete ToOptimizeLoopExtracted; 441d3a533d94dae1e57194001af08763eb3ba199c8fChris Lattner 442d3a533d94dae1e57194001af08763eb3ba199c8fChris Lattner // All of the Function*'s in the MiscompiledFunctions list are in the old 4435313f23b8c3d22a2028beb731c60fc1a25beb149Chris Lattner // module. Update this list to include all of the functions in the 4445313f23b8c3d22a2028beb731c60fc1a25beb149Chris Lattner // optimized and loop extracted module. 4455313f23b8c3d22a2028beb731c60fc1a25beb149Chris Lattner MiscompiledFunctions.clear(); 44690c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { 447ef9b9a793949469cdaa4ab6d0173136229dcab7bReid Spencer Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first); 44856584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer 44990c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner assert(NewF && "Function not found??"); 45090c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner MiscompiledFunctions.push_back(NewF); 451d3a533d94dae1e57194001af08763eb3ba199c8fChris Lattner } 452d3a533d94dae1e57194001af08763eb3ba199c8fChris Lattner 453a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner BD.setNewProgram(ToNotOptimize); 454a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner MadeChange = true; 455a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner } 456a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner} 457a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner 4585e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattnernamespace { 4595e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner class ReduceMiscompiledBlocks : public ListReducer<BasicBlock*> { 4605e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner BugDriver &BD; 46122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool (*TestFn)(BugDriver &, Module *, Module *, std::string &); 4625e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner std::vector<Function*> FunctionsBeingTested; 4635e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner public: 4645e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner ReduceMiscompiledBlocks(BugDriver &bd, 46522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool (*F)(BugDriver &, Module *, Module *, 46622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &), 4675e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner const std::vector<Function*> &Fns) 4685e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner : BD(bd), TestFn(F), FunctionsBeingTested(Fns) {} 4693da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 4705e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner virtual TestResult doTest(std::vector<BasicBlock*> &Prefix, 47122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::vector<BasicBlock*> &Suffix, 47222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &Error) { 47322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Suffix.empty()) { 47422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool Ret = TestFuncs(Suffix, Error); 47522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 47622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return InternalError; 47722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Ret) 47822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return KeepSuffix; 47922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky } 48022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Prefix.empty()) { 48122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool Ret = TestFuncs(Prefix, Error); 48222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 48322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return InternalError; 48422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Ret) 48522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return KeepPrefix; 48622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky } 4875e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner return NoFailure; 4885e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner } 4893da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 49022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool TestFuncs(const std::vector<BasicBlock*> &BBs, std::string &Error); 4915e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner }; 4925e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner} 4935e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 4945e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner/// TestFuncs - Extract all blocks for the miscompiled functions except for the 4955e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner/// specified blocks. If the problem still exists, return true. 4965e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner/// 49722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewyckybool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock*> &BBs, 49822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &Error) { 4995e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner // Test to see if the function is misoptimized if we ONLY run it on the 5005e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner // functions listed in Funcs. 501ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Checking to see if the program is misoptimized when all "; 50268bee938e539d884ee89ce4dfebbad777896960eChris Lattner if (!BBs.empty()) { 503ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "but these " << BBs.size() << " blocks are extracted: "; 50468bee938e539d884ee89ce4dfebbad777896960eChris Lattner for (unsigned i = 0, e = BBs.size() < 10 ? BBs.size() : 10; i != e; ++i) 505ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << BBs[i]->getName() << " "; 506ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman if (BBs.size() > 10) outs() << "..."; 50768bee938e539d884ee89ce4dfebbad777896960eChris Lattner } else { 508ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "blocks are extracted."; 50968bee938e539d884ee89ce4dfebbad777896960eChris Lattner } 510ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << '\n'; 5115e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 5125e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner // Split the module into the two halves of the program we want. 5131ed219a9d2279ce5a5bbcf16d9b7ccc05cce638cRafael Espindola ValueToValueMapTy VMap; 514115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola Module *Clone = CloneModule(BD.getProgram(), VMap); 515115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola Module *Orig = BD.swapProgramIn(Clone); 516115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola std::vector<Function*> FuncsOnClone; 517115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola std::vector<BasicBlock*> BBsOnClone; 518115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola for (unsigned i = 0, e = FunctionsBeingTested.size(); i != e; ++i) { 519115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola Function *F = cast<Function>(VMap[FunctionsBeingTested[i]]); 520115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola FuncsOnClone.push_back(F); 521115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola } 522115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola for (unsigned i = 0, e = BBs.size(); i != e; ++i) { 523115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola BasicBlock *BB = cast<BasicBlock>(VMap[BBs[i]]); 524115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola BBsOnClone.push_back(BB); 525115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola } 526115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola VMap.clear(); 527115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola 528e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap); 5295e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, 530115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola FuncsOnClone, 531e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel VMap); 5325e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 5335e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner // Try the extraction. If it doesn't work, then the block extractor crashed 5345e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner // or something, in which case bugpoint can't chase down this possibility. 535115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola if (Module *New = BD.ExtractMappedBlocksFromModule(BBsOnClone, ToOptimize)) { 5365e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner delete ToOptimize; 537115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola // Run the predicate, 538115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola // note that the predicate will delete both input modules. 539115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola bool Ret = TestFn(BD, New, ToNotOptimize, Error); 540115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola delete BD.swapProgramIn(Orig); 541115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola return Ret; 5425e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner } 543115a932eb9e66efd424664dbd532dbed76faa072Rafael Espindola delete BD.swapProgramIn(Orig); 5445e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner delete ToOptimize; 5455e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner delete ToNotOptimize; 5465e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner return false; 5475e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner} 5485e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 5495e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 5505e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner/// ExtractBlocks - Given a reduced list of functions that still expose the bug, 5515e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner/// extract as many basic blocks from the region as possible without obscuring 5525e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner/// the bug. 5535e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner/// 5545e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattnerstatic bool ExtractBlocks(BugDriver &BD, 55522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool (*TestFn)(BugDriver &, Module *, Module *, 55622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &), 55722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::vector<Function*> &MiscompiledFunctions, 55822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &Error) { 559f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner if (BugpointIsInterrupted) return false; 56056584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer 5615e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner std::vector<BasicBlock*> Blocks; 5625e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) 5635e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner for (Function::iterator I = MiscompiledFunctions[i]->begin(), 5645e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner E = MiscompiledFunctions[i]->end(); I != E; ++I) 5655e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner Blocks.push_back(I); 5665e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 5675e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner // Use the list reducer to identify blocks that can be extracted without 5685e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner // obscuring the bug. The Blocks list will end up containing blocks that must 5695e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner // be retained from the original program. 5705e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner unsigned OldSize = Blocks.size(); 57168bee938e539d884ee89ce4dfebbad777896960eChris Lattner 57268bee938e539d884ee89ce4dfebbad777896960eChris Lattner // Check to see if all blocks are extractible first. 57322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool Ret = ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions) 57422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky .TestFuncs(std::vector<BasicBlock*>(), Error); 57522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 57622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return false; 57722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Ret) { 57868bee938e539d884ee89ce4dfebbad777896960eChris Lattner Blocks.clear(); 57968bee938e539d884ee89ce4dfebbad777896960eChris Lattner } else { 58022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky ReduceMiscompiledBlocks(BD, TestFn, 58122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky MiscompiledFunctions).reduceList(Blocks, Error); 58222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 58322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return false; 58468bee938e539d884ee89ce4dfebbad777896960eChris Lattner if (Blocks.size() == OldSize) 58568bee938e539d884ee89ce4dfebbad777896960eChris Lattner return false; 58668bee938e539d884ee89ce4dfebbad777896960eChris Lattner } 5875e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 5881ed219a9d2279ce5a5bbcf16d9b7ccc05cce638cRafael Espindola ValueToValueMapTy VMap; 589e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel Module *ProgClone = CloneModule(BD.getProgram(), VMap); 5902290e754061f1393bb96b1808ac33dc03399c939Chris Lattner Module *ToExtract = SplitFunctionsOutOfModule(ProgClone, 591d50330cd02b00c8e3de40e8544c45701b9891d87Dan Gohman MiscompiledFunctions, 592e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel VMap); 5932290e754061f1393bb96b1808ac33dc03399c939Chris Lattner Module *Extracted = BD.ExtractMappedBlocksFromModule(Blocks, ToExtract); 5942290e754061f1393bb96b1808ac33dc03399c939Chris Lattner if (Extracted == 0) { 595da895d63377b421dc50117befb2bec80d2973526Chris Lattner // Weird, extraction should have worked. 59665f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << "Nondeterministic problem extracting blocks??\n"; 5972290e754061f1393bb96b1808ac33dc03399c939Chris Lattner delete ProgClone; 5982290e754061f1393bb96b1808ac33dc03399c939Chris Lattner delete ToExtract; 5992290e754061f1393bb96b1808ac33dc03399c939Chris Lattner return false; 6002290e754061f1393bb96b1808ac33dc03399c939Chris Lattner } 6015e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 6022290e754061f1393bb96b1808ac33dc03399c939Chris Lattner // Otherwise, block extraction succeeded. Link the two program fragments back 6032290e754061f1393bb96b1808ac33dc03399c939Chris Lattner // together. 6042290e754061f1393bb96b1808ac33dc03399c939Chris Lattner delete ToExtract; 6055e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 606db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner std::vector<std::pair<std::string, FunctionType*> > MisCompFunctions; 60790c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner for (Module::iterator I = Extracted->begin(), E = Extracted->end(); 60890c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner I != E; ++I) 6095cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer if (!I->isDeclaration()) 610fa1af1344910ee975f50ffdddf605c26f80ef016Chris Lattner MisCompFunctions.push_back(std::make_pair(I->getName(), 611fa1af1344910ee975f50ffdddf605c26f80ef016Chris Lattner I->getFunctionType())); 61290c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner 6132290e754061f1393bb96b1808ac33dc03399c939Chris Lattner std::string ErrorMsg; 614f1f1a4f16128ffa2910f0b1d5c7052b3697f9fcdTanya Lattner if (Linker::LinkModules(ProgClone, Extracted, Linker::DestroySource, 615f1f1a4f16128ffa2910f0b1d5c7052b3697f9fcdTanya Lattner &ErrorMsg)) { 61665f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << BD.getToolName() << ": Error linking modules together:" 61765f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman << ErrorMsg << '\n'; 6182290e754061f1393bb96b1808ac33dc03399c939Chris Lattner exit(1); 6192290e754061f1393bb96b1808ac33dc03399c939Chris Lattner } 62090c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner delete Extracted; 6215e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 6222290e754061f1393bb96b1808ac33dc03399c939Chris Lattner // Set the new program and delete the old one. 6232290e754061f1393bb96b1808ac33dc03399c939Chris Lattner BD.setNewProgram(ProgClone); 6245e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 6252290e754061f1393bb96b1808ac33dc03399c939Chris Lattner // Update the list of miscompiled functions. 6262290e754061f1393bb96b1808ac33dc03399c939Chris Lattner MiscompiledFunctions.clear(); 6275e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 62890c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { 629ef9b9a793949469cdaa4ab6d0173136229dcab7bReid Spencer Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first); 63090c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner assert(NewF && "Function not found??"); 63190c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner MiscompiledFunctions.push_back(NewF); 63290c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner } 6332290e754061f1393bb96b1808ac33dc03399c939Chris Lattner 6342290e754061f1393bb96b1808ac33dc03399c939Chris Lattner return true; 6355e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner} 6365e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 6375e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 638b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner/// DebugAMiscompilation - This is a generic driver to narrow down 639b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner/// miscompilations, either in an optimization or a code generator. 6408c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// 641b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattnerstatic std::vector<Function*> 642b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris LattnerDebugAMiscompilation(BugDriver &BD, 64322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool (*TestFn)(BugDriver &, Module *, Module *, 64422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &), 64522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &Error) { 646640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // Okay, now that we have reduced the list of passes which are causing the 647640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // failure, see if we can pin down which functions are being 648640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // miscompiled... first build a list of all of the non-external functions in 649640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // the program. 650640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner std::vector<Function*> MiscompiledFunctions; 651b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner Module *Prog = BD.getProgram(); 652b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner for (Module::iterator I = Prog->begin(), E = Prog->end(); I != E; ++I) 6535cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer if (!I->isDeclaration()) 654640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner MiscompiledFunctions.push_back(I); 6554a10645c70199c8d8567fbc46312158c419720abChris Lattner 656640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner // Do the reduction... 657f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner if (!BugpointIsInterrupted) 65822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions, 65922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky Error); 6607c863eb8cc34c8ae97ae90672758eb6637b1125fAndrew Trick if (!Error.empty()) { 6617c863eb8cc34c8ae97ae90672758eb6637b1125fAndrew Trick errs() << "\n***Cannot reduce functions: "; 66222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return MiscompiledFunctions; 6637c863eb8cc34c8ae97ae90672758eb6637b1125fAndrew Trick } 664ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "\n*** The following function" 665ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman << (MiscompiledFunctions.size() == 1 ? " is" : "s are") 666ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman << " being miscompiled: "; 667640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner PrintFunctionList(MiscompiledFunctions); 668ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << '\n'; 6694a10645c70199c8d8567fbc46312158c419720abChris Lattner 670a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // See if we can rip any loops out of the miscompiled functions and still 671a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner // trigger the problem. 672dc31a8a70cab3b4c180ac1a482855e31d3fe8e6bReid Spencer 67322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!BugpointIsInterrupted && !DisableLoopExtraction) { 67422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool Ret = ExtractLoops(BD, TestFn, MiscompiledFunctions, Error); 67522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 67622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return MiscompiledFunctions; 67722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Ret) { 67822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky // Okay, we extracted some loops and the problem still appears. See if 67922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky // we can eliminate some of the created functions from being candidates. 68022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky DisambiguateGlobalSymbols(BD.getProgram()); 68122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky 68222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky // Do the reduction... 68322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!BugpointIsInterrupted) 68422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions, 68522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky Error); 68622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 68722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return MiscompiledFunctions; 68822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky 68922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << "\n*** The following function" 69022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << (MiscompiledFunctions.size() == 1 ? " is" : "s are") 69122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << " being miscompiled: "; 69222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky PrintFunctionList(MiscompiledFunctions); 69322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << '\n'; 69422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky } 6955e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner } 6965e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 69722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!BugpointIsInterrupted && !DisableBlockExtraction) { 69822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool Ret = ExtractBlocks(BD, TestFn, MiscompiledFunctions, Error); 69922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 70022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return MiscompiledFunctions; 70122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Ret) { 70222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky // Okay, we extracted some blocks and the problem still appears. See if 70322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky // we can eliminate some of the created functions from being candidates. 70422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky DisambiguateGlobalSymbols(BD.getProgram()); 70522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky 70622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky // Do the reduction... 70722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions, 70822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky Error); 70922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 71022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return MiscompiledFunctions; 71122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky 71222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << "\n*** The following function" 71322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << (MiscompiledFunctions.size() == 1 ? " is" : "s are") 71422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << " being miscompiled: "; 71522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky PrintFunctionList(MiscompiledFunctions); 71622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << '\n'; 71722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky } 718a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner } 719a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner 720b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner return MiscompiledFunctions; 721b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner} 722b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner 723a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner/// TestOptimizer - This is the predicate function used to check to see if the 724a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner/// "Test" portion of the program is misoptimized. If so, return true. In any 725a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner/// case, both module arguments are deleted. 7268c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// 72722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewyckystatic bool TestOptimizer(BugDriver &BD, Module *Test, Module *Safe, 72822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &Error) { 729b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner // Run the optimization passes on ToOptimize, producing a transformed version 730b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner // of the functions being tested. 731ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " Optimizing functions being tested: "; 732b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner Module *Optimized = BD.runPassesOn(Test, BD.getPassesToRun(), 733b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner /*AutoDebugCrashes*/true); 734ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "done.\n"; 735b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner delete Test; 736b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner 737ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " Checking to see if the merged program executes correctly: "; 73813793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola bool Broken; 73913793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola Module *New = TestMergedProgram(BD, Optimized, Safe, true, Error, Broken); 74013793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola if (New) { 74113793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola outs() << (Broken ? " nope.\n" : " yup.\n"); 74213793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola // Delete the original and set the new program. 74313793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola delete BD.swapProgramIn(New); 74413793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola } 745b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner return Broken; 746b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner} 747b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner 748b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner 749b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner/// debugMiscompilation - This method is used when the passes selected are not 750b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner/// crashing, but the generated output is semantically different from the 751b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner/// input. 752b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner/// 75322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewyckyvoid BugDriver::debugMiscompilation(std::string *Error) { 754b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner // Make sure something was miscompiled... 755f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner if (!BugpointIsInterrupted) 75622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!ReduceMiscompilingPasses(*this).reduceList(PassesToRun, *Error)) { 75722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Error->empty()) 75822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky errs() << "*** Optimized program matches reference output! No problem" 75922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << " detected...\nbugpoint can't help you with your problem!\n"; 76022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return; 761f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner } 762b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner 763ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "\n*** Found miscompiling pass" 764ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman << (getPassesToRun().size() == 1 ? "" : "es") << ": " 765ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman << getPassesString(getPassesToRun()) << '\n'; 766bae1b71cbb930e419df03db209ebc547a0e4ec72Rafael Espindola EmitProgressBitcode(Program, "passinput"); 767b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner 76856584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer std::vector<Function *> MiscompiledFunctions = 76922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky DebugAMiscompilation(*this, TestOptimizer, *Error); 77022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error->empty()) 77122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return; 772b15825b0a29e527b361b63a6e41aff5fdb8fdd5aChris Lattner 7738ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif // Output a bunch of bitcode files for the user... 774ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Outputting reduced bitcode files which expose the problem:\n"; 7751ed219a9d2279ce5a5bbcf16d9b7ccc05cce638cRafael Espindola ValueToValueMapTy VMap; 776e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel Module *ToNotOptimize = CloneModule(getProgram(), VMap); 777efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, 778d50330cd02b00c8e3de40e8544c45701b9891d87Dan Gohman MiscompiledFunctions, 779e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel VMap); 780be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner 781ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " Non-optimized portion: "; 782bae1b71cbb930e419df03db209ebc547a0e4ec72Rafael Espindola EmitProgressBitcode(ToNotOptimize, "tonotoptimize", true); 783bae1b71cbb930e419df03db209ebc547a0e4ec72Rafael Espindola delete ToNotOptimize; // Delete hacked module. 7843da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 785ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " Portion that is input to optimizer: "; 786bae1b71cbb930e419df03db209ebc547a0e4ec72Rafael Espindola EmitProgressBitcode(ToOptimize, "tooptimize"); 787bae1b71cbb930e419df03db209ebc547a0e4ec72Rafael Espindola delete ToOptimize; // Delete hacked module. 7884a10645c70199c8d8567fbc46312158c419720abChris Lattner 78922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return; 7904a10645c70199c8d8567fbc46312158c419720abChris Lattner} 791d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 792a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner/// CleanupAndPrepareModules - Get the specified modules ready for code 793a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner/// generator testing. 7948c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// 795a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattnerstatic void CleanupAndPrepareModules(BugDriver &BD, Module *&Test, 796a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner Module *Safe) { 797a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Clean up the modules, removing extra cruft that we don't need anymore... 798a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner Test = BD.performFinalCleanups(Test); 799a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 800a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // If we are executing the JIT, we have several nasty issues to take care of. 801a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner if (!BD.isExecutingJIT()) return; 802a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 803a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // First, if the main function is in the Safe module, we must add a stub to 804a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // the Test module to call into it. Thus, we create a new function `main' 805a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // which just calls the old one. 806688b0490e22eb67623f5aaa24406209be74efcb2Reid Spencer if (Function *oldMain = Safe->getFunction("main")) 8075cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer if (!oldMain->isDeclaration()) { 808a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Rename it 809a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner oldMain->setName("llvm_bugpoint_old_main"); 810a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Create a NEW `main' function with same type in the test module. 811051a950000e21935165db56695e35bade668193bGabor Greif Function *newMain = Function::Create(oldMain->getFunctionType(), 812051a950000e21935165db56695e35bade668193bGabor Greif GlobalValue::ExternalLinkage, 813051a950000e21935165db56695e35bade668193bGabor Greif "main", Test); 814a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Create an `oldmain' prototype in the test module, which will 815a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // corresponds to the real main function in the same module. 816051a950000e21935165db56695e35bade668193bGabor Greif Function *oldMainProto = Function::Create(oldMain->getFunctionType(), 817051a950000e21935165db56695e35bade668193bGabor Greif GlobalValue::ExternalLinkage, 818051a950000e21935165db56695e35bade668193bGabor Greif oldMain->getName(), Test); 819a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Set up and remember the argument list for the main function. 820a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner std::vector<Value*> args; 8215a1c58d0094ff16dcd103f3752046d426ad5dd2cAlkis Evlogimenos for (Function::arg_iterator 8225a1c58d0094ff16dcd103f3752046d426ad5dd2cAlkis Evlogimenos I = newMain->arg_begin(), E = newMain->arg_end(), 8235a1c58d0094ff16dcd103f3752046d426ad5dd2cAlkis Evlogimenos OI = oldMain->arg_begin(); I != E; ++I, ++OI) { 8246bc41e8a74d1756da0003641bfebd02a3d6d9586Owen Anderson I->setName(OI->getName()); // Copy argument names from oldMain 825a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner args.push_back(I); 826a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner } 827a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 828a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Call the old main function and return its result 8291d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *BB = BasicBlock::Create(Safe->getContext(), "entry", newMain); 830a3efbb15ddd5aa9006564cd79086723640084878Jay Foad CallInst *call = CallInst::Create(oldMainProto, args, "", BB); 8313da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 832a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // If the type of old function wasn't void, return value of call 8331d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ReturnInst::Create(Safe->getContext(), call, BB); 834a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner } 835a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 836a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // The second nasty issue we must deal with in the JIT is that the Safe 837a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // module cannot directly reference any functions defined in the test 838a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // module. Instead, we use a JIT API call to dynamically resolve the 839a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // symbol. 8403da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 841a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Add the resolver to the Safe module. 842a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Prototype: void *getPointerToNamedFunction(const char* Name) 8432db43c864e8372823d961d961ca520ed20edca82Chris Lattner Constant *resolverFunc = 844a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner Safe->getOrInsertFunction("getPointerToNamedFunction", 845ac53a0b272452013124bfc70480aea5e41b60f40Duncan Sands Type::getInt8PtrTy(Safe->getContext()), 846ac53a0b272452013124bfc70480aea5e41b60f40Duncan Sands Type::getInt8PtrTy(Safe->getContext()), 8471d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson (Type *)0); 8483da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 849a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Use the function we just added to get addresses of functions we need. 850dc7fef83dcab053f86119d00478e6b008166fcf5Misha Brukman for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) { 8515cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer if (F->isDeclaration() && !F->use_empty() && &*F != resolverFunc && 852a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands !F->isIntrinsic() /* ignore intrinsics */) { 853688b0490e22eb67623f5aaa24406209be74efcb2Reid Spencer Function *TestFn = Test->getFunction(F->getName()); 854a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 855a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Don't forward functions which are external in the test module too. 8565cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer if (TestFn && !TestFn->isDeclaration()) { 857a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // 1. Add a string constant with its name to the global file 85818c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner Constant *InitArray = 85918c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner ConstantDataArray::getString(F->getContext(), F->getName()); 860a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner GlobalVariable *funcName = 861e9b11b431308f4766b73cda93e38ec930c912122Owen Anderson new GlobalVariable(*Safe, InitArray->getType(), true /*isConstant*/, 8623da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman GlobalValue::InternalLinkage, InitArray, 863e9b11b431308f4766b73cda93e38ec930c912122Owen Anderson F->getName() + "_name"); 864a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 865a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // 2. Use `GetElementPtr *funcName, 0, 0' to convert the string to an 866a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // sbyte* so it matches the signature of the resolver function. 867a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 868a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // GetElementPtr *funcName, ulong 0, ulong 0 8691d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson std::vector<Constant*> GEPargs(2, 8701d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Constant::getNullValue(Type::getInt32Ty(F->getContext()))); 871dab3d29605a5c83db41b28176273ef55961120c1Jay Foad Value *GEP = ConstantExpr::getGetElementPtr(funcName, GEPargs); 872a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner std::vector<Value*> ResolverArgs; 873a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner ResolverArgs.push_back(GEP); 874a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 875de4803d0af6824a2d5da41fa09b512084c73ce34Misha Brukman // Rewrite uses of F in global initializers, etc. to uses of a wrapper 876de4803d0af6824a2d5da41fa09b512084c73ce34Misha Brukman // function that dynamically resolves the calls to F via our JIT API 877a3efca16f2688981672deeb718909cf6acbe474eChris Lattner if (!F->use_empty()) { 878a3efca16f2688981672deeb718909cf6acbe474eChris Lattner // Create a new global to hold the cached function pointer. 8799e9a0d5fc26878e51a58a8b57900fcbf952c2691Owen Anderson Constant *NullPtr = ConstantPointerNull::get(F->getType()); 880a3efca16f2688981672deeb718909cf6acbe474eChris Lattner GlobalVariable *Cache = 88156584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer new GlobalVariable(*F->getParent(), F->getType(), 882e9b11b431308f4766b73cda93e38ec930c912122Owen Anderson false, GlobalValue::InternalLinkage, 883e9b11b431308f4766b73cda93e38ec930c912122Owen Anderson NullPtr,F->getName()+".fpcache"); 88400b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 885de4803d0af6824a2d5da41fa09b512084c73ce34Misha Brukman // Construct a new stub function that will re-route calls to F 886db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FuncTy = F->getFunctionType(); 887051a950000e21935165db56695e35bade668193bGabor Greif Function *FuncWrapper = Function::Create(FuncTy, 888051a950000e21935165db56695e35bade668193bGabor Greif GlobalValue::InternalLinkage, 889051a950000e21935165db56695e35bade668193bGabor Greif F->getName() + "_wrapper", 890051a950000e21935165db56695e35bade668193bGabor Greif F->getParent()); 8911d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *EntryBB = BasicBlock::Create(F->getContext(), 8921d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson "entry", FuncWrapper); 8931d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *DoCallBB = BasicBlock::Create(F->getContext(), 8941d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson "usecache", FuncWrapper); 8951d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *LookupBB = BasicBlock::Create(F->getContext(), 8961d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson "lookupfp", FuncWrapper); 89700b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 898a3efca16f2688981672deeb718909cf6acbe474eChris Lattner // Check to see if we already looked up the value. 899a3efca16f2688981672deeb718909cf6acbe474eChris Lattner Value *CachedVal = new LoadInst(Cache, "fpcache", EntryBB); 900333c40096561218bc3597cf153c0a3895274414cOwen Anderson Value *IsNull = new ICmpInst(*EntryBB, ICmpInst::ICMP_EQ, CachedVal, 901333c40096561218bc3597cf153c0a3895274414cOwen Anderson NullPtr, "isNull"); 902051a950000e21935165db56695e35bade668193bGabor Greif BranchInst::Create(LookupBB, DoCallBB, IsNull, EntryBB); 90300b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 904de4803d0af6824a2d5da41fa09b512084c73ce34Misha Brukman // Resolve the call to function F via the JIT API: 905de4803d0af6824a2d5da41fa09b512084c73ce34Misha Brukman // 906de4803d0af6824a2d5da41fa09b512084c73ce34Misha Brukman // call resolver(GetElementPtr...) 907b1dbcd886a4b5597a839f299054b78b33fb2d6dfGabor Greif CallInst *Resolver = 908a3efbb15ddd5aa9006564cd79086723640084878Jay Foad CallInst::Create(resolverFunc, ResolverArgs, "resolver", LookupBB); 909b1dbcd886a4b5597a839f299054b78b33fb2d6dfGabor Greif 910b1dbcd886a4b5597a839f299054b78b33fb2d6dfGabor Greif // Cast the result from the resolver to correctly-typed function. 911b1dbcd886a4b5597a839f299054b78b33fb2d6dfGabor Greif CastInst *CastedResolver = 912b1dbcd886a4b5597a839f299054b78b33fb2d6dfGabor Greif new BitCastInst(Resolver, 913debcb01b0f0a15f568ca69e8f288fade4bfc7297Owen Anderson PointerType::getUnqual(F->getFunctionType()), 914b1dbcd886a4b5597a839f299054b78b33fb2d6dfGabor Greif "resolverCast", LookupBB); 9153da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencer 916a3efca16f2688981672deeb718909cf6acbe474eChris Lattner // Save the value in our cache. 917a3efca16f2688981672deeb718909cf6acbe474eChris Lattner new StoreInst(CastedResolver, Cache, LookupBB); 918051a950000e21935165db56695e35bade668193bGabor Greif BranchInst::Create(DoCallBB, LookupBB); 91900b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 9203ecfc861b4365f341c5c969b40e1afccde676e6fJay Foad PHINode *FuncPtr = PHINode::Create(NullPtr->getType(), 2, 921b1dbcd886a4b5597a839f299054b78b33fb2d6dfGabor Greif "fp", DoCallBB); 922a3efca16f2688981672deeb718909cf6acbe474eChris Lattner FuncPtr->addIncoming(CastedResolver, LookupBB); 923a3efca16f2688981672deeb718909cf6acbe474eChris Lattner FuncPtr->addIncoming(CachedVal, EntryBB); 92400b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 925a3efca16f2688981672deeb718909cf6acbe474eChris Lattner // Save the argument list. 926dc7fef83dcab053f86119d00478e6b008166fcf5Misha Brukman std::vector<Value*> Args; 9275a1c58d0094ff16dcd103f3752046d426ad5dd2cAlkis Evlogimenos for (Function::arg_iterator i = FuncWrapper->arg_begin(), 9285a1c58d0094ff16dcd103f3752046d426ad5dd2cAlkis Evlogimenos e = FuncWrapper->arg_end(); i != e; ++i) 929dc7fef83dcab053f86119d00478e6b008166fcf5Misha Brukman Args.push_back(i); 930dc7fef83dcab053f86119d00478e6b008166fcf5Misha Brukman 931dc7fef83dcab053f86119d00478e6b008166fcf5Misha Brukman // Pass on the arguments to the real function, return its result 932e49a13e7260b83ce56d01446f2a165cc9f35da7fDan Gohman if (F->getReturnType()->isVoidTy()) { 933a3efbb15ddd5aa9006564cd79086723640084878Jay Foad CallInst::Create(FuncPtr, Args, "", DoCallBB); 9341d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ReturnInst::Create(F->getContext(), DoCallBB); 935dc7fef83dcab053f86119d00478e6b008166fcf5Misha Brukman } else { 936a3efbb15ddd5aa9006564cd79086723640084878Jay Foad CallInst *Call = CallInst::Create(FuncPtr, Args, 937051a950000e21935165db56695e35bade668193bGabor Greif "retval", DoCallBB); 9381d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ReturnInst::Create(F->getContext(),Call, DoCallBB); 939dc7fef83dcab053f86119d00478e6b008166fcf5Misha Brukman } 94000b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 941de4803d0af6824a2d5da41fa09b512084c73ce34Misha Brukman // Use the wrapper function instead of the old function 942de4803d0af6824a2d5da41fa09b512084c73ce34Misha Brukman F->replaceAllUsesWith(FuncWrapper); 943dc7fef83dcab053f86119d00478e6b008166fcf5Misha Brukman } 944a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner } 945a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner } 946a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner } 947a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 948a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner if (verifyModule(*Test) || verifyModule(*Safe)) { 94965f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << "Bugpoint has a bug, which corrupted a module!!\n"; 950a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner abort(); 951a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner } 952a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner} 953a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 954a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 955a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 956a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner/// TestCodeGenerator - This is the predicate function used to check to see if 957a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner/// the "Test" portion of the program is miscompiled by the code generator under 958a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner/// test. If so, return true. In any case, both module arguments are deleted. 9598c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// 96022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewyckystatic bool TestCodeGenerator(BugDriver &BD, Module *Test, Module *Safe, 96122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &Error) { 962a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner CleanupAndPrepareModules(BD, Test, Safe); 963a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 96488088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola SmallString<128> TestModuleBC; 96588088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola int TestModuleFD; 9661276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc", 9671276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola TestModuleFD, TestModuleBC); 96888088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola if (EC) { 96965f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << BD.getToolName() << "Error making unique filename: " 97088088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola << EC.message() << "\n"; 97151c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer exit(1); 97251c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer } 97388088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola if (BD.writeProgramToFile(TestModuleBC.str(), TestModuleFD, Test)) { 97474382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner errs() << "Error writing bitcode to `" << TestModuleBC.str() 97574382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner << "'\nExiting."; 976a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner exit(1); 977a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner } 978a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner delete Test; 979a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 980c9c08fb3a7fb5e8ea3e1477a88507704c7a70ba1Michael J. Spencer FileRemover TestModuleBCRemover(TestModuleBC.str(), !SaveTemps); 981bc2ed599e877b9d76bd548546019f98ae256fe9bRafael Espindola 982a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Make the shared library 98388088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola SmallString<128> SafeModuleBC; 98488088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola int SafeModuleFD; 9851276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD, 9861276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola SafeModuleBC); 98788088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola if (EC) { 98865f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << BD.getToolName() << "Error making unique filename: " 98988088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola << EC.message() << "\n"; 99051c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer exit(1); 99151c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer } 992a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 99388088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola if (BD.writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, Safe)) { 99474382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner errs() << "Error writing bitcode to `" << SafeModuleBC.str() 99574382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner << "'\nExiting."; 996a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner exit(1); 997a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner } 998bc2ed599e877b9d76bd548546019f98ae256fe9bRafael Espindola 999c9c08fb3a7fb5e8ea3e1477a88507704c7a70ba1Michael J. Spencer FileRemover SafeModuleBCRemover(SafeModuleBC.str(), !SaveTemps); 1000bc2ed599e877b9d76bd548546019f98ae256fe9bRafael Espindola 100122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string SharedObject = BD.compileSharedObject(SafeModuleBC.str(), Error); 100222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 10032706387d37b30fc191c5b74987dc139e1835c52dBenjamin Kramer return false; 1004a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner delete Safe; 1005a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 1006c9c08fb3a7fb5e8ea3e1477a88507704c7a70ba1Michael J. Spencer FileRemover SharedObjectRemover(SharedObject, !SaveTemps); 1007bc2ed599e877b9d76bd548546019f98ae256fe9bRafael Espindola 1008a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Run the code generator on the `Test' code, loading the shared library. 1009a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // The function returns whether or not the new output differs from reference. 101010757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola bool Result = BD.diffProgram(BD.getProgram(), TestModuleBC.str(), 101110757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola SharedObject, false, &Error); 101222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) 101322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return false; 1014a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 1015a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner if (Result) 101665f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << ": still failing!\n"; 1017a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner else 101865f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << ": didn't fail.\n"; 1019a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 1020a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner return Result; 1021a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner} 1022a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 1023a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 10248c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// debugCodeGenerator - debug errors in LLC, LLI, or CBE. 10258c194eaa0577a207bb1ea91bf2c2a5e664fce9eeMisha Brukman/// 102622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewyckybool BugDriver::debugCodeGenerator(std::string *Error) { 102770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman if ((void*)SafeInterpreter == (void*)Interpreter) { 102810757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola std::string Result = executeProgramSafely(Program, "bugpoint.safe.out", 102910757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola Error); 103022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Error->empty()) { 103122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << "\n*** The \"safe\" i.e. 'known good' backend cannot match " 103222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << "the reference diff. This may be due to a\n front-end " 103322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << "bug or a bug in the original program, but this can also " 103422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << "happen if bugpoint isn't running the program with the " 103522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << "right flags or input.\n I left the result of executing " 103622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << "the program with the \"safe\" backend in this file for " 103722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << "you: '" 103822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << Result << "'.\n"; 103922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky } 1040a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner return true; 1041a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner } 1042a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 1043a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner DisambiguateGlobalSymbols(Program); 1044a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 104522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::vector<Function*> Funcs = DebugAMiscompilation(*this, TestCodeGenerator, 104622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky *Error); 104722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error->empty()) 104822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return true; 1049a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 1050a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Split the module into the two halves of the program we want. 10511ed219a9d2279ce5a5bbcf16d9b7ccc05cce638cRafael Espindola ValueToValueMapTy VMap; 1052e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel Module *ToNotCodeGen = CloneModule(getProgram(), VMap); 1053e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel Module *ToCodeGen = SplitFunctionsOutOfModule(ToNotCodeGen, Funcs, VMap); 1054a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 1055a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Condition the modules 1056a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner CleanupAndPrepareModules(*this, ToCodeGen, ToNotCodeGen); 1057a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 105888088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola SmallString<128> TestModuleBC; 105988088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola int TestModuleFD; 10601276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc", 10611276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola TestModuleFD, TestModuleBC); 106288088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola if (EC) { 106365f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << getToolName() << "Error making unique filename: " 106488088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola << EC.message() << "\n"; 106551c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer exit(1); 106651c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer } 106797182985d530dbef488696c95a39c14fe56c995bReid Spencer 106888088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola if (writeProgramToFile(TestModuleBC.str(), TestModuleFD, ToCodeGen)) { 106974382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner errs() << "Error writing bitcode to `" << TestModuleBC.str() 107074382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner << "'\nExiting."; 1071a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner exit(1); 1072a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner } 1073a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner delete ToCodeGen; 1074a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 1075a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner // Make the shared library 107688088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola SmallString<128> SafeModuleBC; 107788088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola int SafeModuleFD; 10781276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD, 10791276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola SafeModuleBC); 108088088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola if (EC) { 108165f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << getToolName() << "Error making unique filename: " 108288088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola << EC.message() << "\n"; 108351c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer exit(1); 108451c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer } 108597182985d530dbef488696c95a39c14fe56c995bReid Spencer 108688088f4067ae002aebf6e32079c446b06fab31f1Rafael Espindola if (writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, ToNotCodeGen)) { 108774382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner errs() << "Error writing bitcode to `" << SafeModuleBC.str() 108874382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner << "'\nExiting."; 1089a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner exit(1); 1090a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner } 109122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string SharedObject = compileSharedObject(SafeModuleBC.str(), *Error); 109222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error->empty()) 109322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return true; 1094a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner delete ToNotCodeGen; 1095a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 1096ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "You can reproduce the problem with the command line: \n"; 1097a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner if (isExecutingJIT()) { 109874382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner outs() << " lli -load " << SharedObject << " " << TestModuleBC.str(); 1099a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner } else { 11008d0e1bcc921c942e979b0925051c663590bd618fNick Lewycky outs() << " llc " << TestModuleBC.str() << " -o " << TestModuleBC.str() 110174382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner << ".s\n"; 110274382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner outs() << " gcc " << SharedObject << " " << TestModuleBC.str() 110374382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner << ".s -o " << TestModuleBC.str() << ".exe"; 110459615f0f85e2ac99e012cb81934d002faebd405aChris Lattner#if defined (HAVE_LINK_R) 1105ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " -Wl,-R."; 110659615f0f85e2ac99e012cb81934d002faebd405aChris Lattner#endif 1107ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "\n"; 110874382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner outs() << " " << TestModuleBC.str() << ".exe"; 1109a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner } 111022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky for (unsigned i = 0, e = InputArgv.size(); i != e; ++i) 1111ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " " << InputArgv[i]; 1112ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << '\n'; 1113ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "The shared object was created with:\n llc -march=c " 111474382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner << SafeModuleBC.str() << " -o temporary.c\n" 1115ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar << " gcc -xc temporary.c -O2 -o " << SharedObject; 1116ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar if (TargetTriple.getArch() == Triple::sparc) 1117ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar outs() << " -G"; // Compile a shared library, `-G' for Sparc 1118ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar else 1119ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar outs() << " -fPIC -shared"; // `-shared' for Linux/X86, maybe others 1120ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar 1121ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar outs() << " -fno-strict-aliasing\n"; 1122a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner 1123a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner return false; 1124a57d86b436549503a7f96c5266444e022bdbaf55Chris Lattner} 1125