From daniel at zuster.org Mon Nov 9 00:08:28 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 09 Nov 2009 06:08:28 -0000 Subject: [llvm-commits] [zorg] r86519 - /zorg/trunk/zorg/buildbot/builders/ClangBuilder.py Message-ID: <200911090608.nA968TpF010765@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Nov 9 00:08:28 2009 New Revision: 86519 URL: http://llvm.org/viewvc/llvm-project?rev=86519&view=rev Log: Add some more options to the Clang build factory. Modified: zorg/trunk/zorg/buildbot/builders/ClangBuilder.py Modified: zorg/trunk/zorg/buildbot/builders/ClangBuilder.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/zorg/buildbot/builders/ClangBuilder.py?rev=86519&r1=86518&r2=86519&view=diff ============================================================================== --- zorg/trunk/zorg/buildbot/builders/ClangBuilder.py (original) +++ zorg/trunk/zorg/buildbot/builders/ClangBuilder.py Mon Nov 9 00:08:28 2009 @@ -11,7 +11,8 @@ from zorg.buildbot.commands.ClangTestCommand import ClangTestCommand from zorg.buildbot.commands.BatchFileDownload import BatchFileDownload -def getClangBuildFactory(triple, clean=True, test=True): +def getClangBuildFactory(triple=None, clean=True, test=True, + expensive_checks=False, run_cxx_tests=False, valgrind=False): f = buildbot.process.factory.BuildFactory() # Determine the build directory. @@ -30,13 +31,21 @@ mode='update', baseURL='http://llvm.org/svn/llvm-project/cfe/', defaultBranch='trunk', workdir='llvm/tools/clang')) - f.addStep(Configure(command=['./configure', - '--build', triple, - '--host', triple, - '--target', triple], + + # Force without llvm-gcc so we don't run afoul of Frontend test failures. + configure_args = ["./configure", "--without-llvmgcc", "--without-llvmgxx"] + config_name = 'Debug' + if expensive_checks: + configure_args.append('--enable-expensive-checks') + config_name += '+Checks' + if triple: + configure_args += ['--build=%s' % triple, + '--host=%s' % triple, + '--target=%s' % triple] + f.addStep(Configure(command=configure_args, workdir='llvm', - description=['configuring','Debug'], - descriptionDone=['configure','Debug'])) + description=['configuring',config_name], + descriptionDone=['configure',config_name])) if clean: f.addStep(WarningCountingShellCommand(name="clean-llvm", command="make clean", @@ -50,6 +59,14 @@ description="compiling llvm & clang", descriptionDone="compile llvm & clang", workdir='llvm')) + clangTestArgs = '-v' + if valgrind: + clangTestArgs += ' --vg ' + clangTestArgs += ' --vg-arg --leak-check=no' + clangTestArgs += ' --vg-arg --suppressions=%(builddir)s/llvm/tools/clang/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp' + extraTestDirs = '' + if run_cxx_tests: + extraTestDirs += '%(builddir)s/llvm/tools/clang/utils/C++Tests' if test: f.addStep(ClangTestCommand(name='test-llvm', command=["make", "check-lit", "VERBOSE=1"], @@ -57,7 +74,8 @@ descriptionDone=["test", "llvm"], workdir='llvm')) f.addStep(ClangTestCommand(name='test-clang', - command=WithProperties("nice -n 10 make test VERBOSE=1"), + command=['make', 'test', WithProperties('TESTARGS=%s' % clangTestArgs), + WithProperties('EXTRA_TESTDIRS=%s' % extraTestDirs)], workdir='llvm/tools/clang')) return f From daniel at zuster.org Mon Nov 9 00:08:36 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 09 Nov 2009 06:08:36 -0000 Subject: [llvm-commits] [zorg] r86520 - /zorg/trunk/zorg/buildbot/util/ConfigEmailLookup.py Message-ID: <200911090608.nA968aCg010780@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Nov 9 00:08:36 2009 New Revision: 86520 URL: http://llvm.org/viewvc/llvm-project?rev=86520&view=rev Log: Add an optional only_addresses regular expression, which can be used to filter the email lookups (non-matches will go to the default address). Modified: zorg/trunk/zorg/buildbot/util/ConfigEmailLookup.py Modified: zorg/trunk/zorg/buildbot/util/ConfigEmailLookup.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/zorg/buildbot/util/ConfigEmailLookup.py?rev=86520&r1=86519&r2=86520&view=diff ============================================================================== --- zorg/trunk/zorg/buildbot/util/ConfigEmailLookup.py (original) +++ zorg/trunk/zorg/buildbot/util/ConfigEmailLookup.py Mon Nov 9 00:08:36 2009 @@ -7,20 +7,35 @@ file to match commit authors to email addresses. """ + # FIXME: This should be able to reload the config file when it + # changes. + zope.interface.implements(buildbot.interfaces.IEmailLookup) - compare_attrs = ["author_filename", "default_address"] + compare_attrs = ["author_filename", "default_address", "only_addresses"] - def __init__(self, author_filename, default_address): + def __init__(self, author_filename, default_address, only_addresses = None): from ConfigParser import ConfigParser self.author_filename = author_filename self.default_address = default_address + self.only_addresses = only_addresses self.config_parser = ConfigParser() self.config_parser.read(author_filename) + if only_addresses: + import re + self.address_match_p = re.compile(only_addresses).match + else: + self.address_match_p = lambda addr: True + def getAddress(self, name): try: - return self.config_parser.get("authors", name) + email = self.config_parser.get("authors", name) except: return self.default_address + + if self.address_match_p(email): + return email + + return self.default_address From evan.cheng at apple.com Mon Nov 9 00:49:22 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 09 Nov 2009 06:49:22 -0000 Subject: [llvm-commits] [llvm] r86521 - /llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Message-ID: <200911090649.nA96nM21012250@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 9 00:49:22 2009 New Revision: 86521 URL: http://llvm.org/viewvc/llvm-project?rev=86521&view=rev Log: 80 col. Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp?rev=86521&r1=86520&r2=86521&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp (original) +++ llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Mon Nov 9 00:49:22 2009 @@ -39,8 +39,10 @@ using namespace llvm; static cl::opt PreSplitLimit("pre-split-limit", cl::init(-1), cl::Hidden); -static cl::opt DeadSplitLimit("dead-split-limit", cl::init(-1), cl::Hidden); -static cl::opt RestoreFoldLimit("restore-fold-limit", cl::init(-1), cl::Hidden); +static cl::opt DeadSplitLimit("dead-split-limit", cl::init(-1), + cl::Hidden); +static cl::opt RestoreFoldLimit("restore-fold-limit", cl::init(-1), + cl::Hidden); STATISTIC(NumSplits, "Number of intervals split"); STATISTIC(NumRemats, "Number of intervals split by rematerialization"); From evan.cheng at apple.com Mon Nov 9 00:49:37 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 09 Nov 2009 06:49:37 -0000 Subject: [llvm-commits] [llvm] r86522 - in /llvm/trunk/lib/CodeGen: LiveIntervalAnalysis.cpp SelectionDAG/SelectionDAGISel.cpp Message-ID: <200911090649.nA96nb8x012271@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 9 00:49:37 2009 New Revision: 86522 URL: http://llvm.org/viewvc/llvm-project?rev=86522&view=rev Log: Hide a couple of options. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=86522&r1=86521&r2=86522&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Mon Nov 9 00:49:37 2009 @@ -53,7 +53,8 @@ static cl::opt EnableFastSpilling("fast-spill", cl::init(false), cl::Hidden); -static cl::opt EarlyCoalescing("early-coalescing", cl::init(false)); +static cl::opt EarlyCoalescing("early-coalescing", + cl::init(false), cl::Hidden); static cl::opt CoalescingLimit("early-coalescing-limit", cl::init(-1), cl::Hidden); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=86522&r1=86521&r2=86522&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Nov 9 00:49:37 2009 @@ -68,7 +68,7 @@ EnableFastISelAbort("fast-isel-abort", cl::Hidden, cl::desc("Enable abort calls when \"fast\" instruction fails")); static cl::opt -SchedLiveInCopies("schedule-livein-copies", +SchedLiveInCopies("schedule-livein-copies", cl::Hidden, cl::desc("Schedule copies of livein registers"), cl::init(false)); From sabre at nondot.org Mon Nov 9 01:07:57 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 09 Nov 2009 07:07:57 -0000 Subject: [llvm-commits] [llvm] r86524 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/intrinsics.ll Message-ID: <200911090707.nA977vA9012870@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 01:07:56 2009 New Revision: 86524 URL: http://llvm.org/viewvc/llvm-project?rev=86524&view=rev Log: if a 'with overflow' intrinsic just has the normal result used, simplify it to a normal binop. Patch by Alastair Lynn, testcase by me. Added: llvm/trunk/test/Transforms/InstCombine/intrinsics.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=86524&r1=86523&r2=86524&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Nov 9 01:07:56 2009 @@ -12452,6 +12452,47 @@ return ExtractValueInst::Create(IV->getInsertedValueOperand(), exti, exte); } + if (IntrinsicInst *II = dyn_cast(Agg)) { + // We're extracting from an intrinsic, see if we're the only user, which + // allows us to simplify multiple result intrinsics to simpler things that + // just get one value.. + if (II->hasOneUse()) { + // Check if we're grabbing the overflow bit or the result of a 'with + // overflow' intrinsic. If it's the latter we can remove the intrinsic + // and replace it with a traditional binary instruction. + switch (II->getIntrinsicID()) { + case Intrinsic::uadd_with_overflow: + case Intrinsic::sadd_with_overflow: + if (*EV.idx_begin() == 0) { // Normal result. + Value *LHS = II->getOperand(1), *RHS = II->getOperand(2); + II->replaceAllUsesWith(UndefValue::get(II->getType())); + EraseInstFromFunction(*II); + return BinaryOperator::CreateAdd(LHS, RHS); + } + break; + case Intrinsic::usub_with_overflow: + case Intrinsic::ssub_with_overflow: + if (*EV.idx_begin() == 0) { // Normal result. + Value *LHS = II->getOperand(1), *RHS = II->getOperand(2); + II->replaceAllUsesWith(UndefValue::get(II->getType())); + EraseInstFromFunction(*II); + return BinaryOperator::CreateSub(LHS, RHS); + } + break; + case Intrinsic::umul_with_overflow: + case Intrinsic::smul_with_overflow: + if (*EV.idx_begin() == 0) { // Normal result. + Value *LHS = II->getOperand(1), *RHS = II->getOperand(2); + II->replaceAllUsesWith(UndefValue::get(II->getType())); + EraseInstFromFunction(*II); + return BinaryOperator::CreateMul(LHS, RHS); + } + break; + default: + break; + } + } + } // Can't simplify extracts from other values. Note that nested extracts are // already simplified implicitely by the above (extract ( extract (insert) ) // will be translated into extract ( insert ( extract ) ) first and then just Added: llvm/trunk/test/Transforms/InstCombine/intrinsics.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/intrinsics.ll?rev=86524&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/intrinsics.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/intrinsics.ll Mon Nov 9 01:07:56 2009 @@ -0,0 +1,12 @@ +; RUN: opt %s -instcombine -S | FileCheck %s + +declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8) + +define i8 @test1(i8 %A, i8 %B) { + %x = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %A, i8 %B) + %y = extractvalue {i8, i1} %x, 0 + ret i8 %y +; CHECK: @test1 +; CHECK-NEXT: %y = add i8 %A, %B +; CHECK-NEXT: ret i8 %y +} From clattner at apple.com Mon Nov 9 01:09:03 2009 From: clattner at apple.com (Chris Lattner) Date: Sun, 8 Nov 2009 23:09:03 -0800 Subject: [llvm-commits] Patch: simplification of overflow operations In-Reply-To: References: Message-ID: On Nov 6, 2009, at 11:52 PM, Alastair Lynn wrote: > Hello- > > The attached patch will simplify cases where overflow intrinsics are > used but the overflow bit is not to the equivalent basic > instructions (llvm.uadd.with.overflow => add, for instance). > > This is my first patch, please don't judge me too harshly! Thanks, applied in r86524 with some minor formatting changes, I also added a testcase: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20091109/090673.html It would also be nice to simplify the case when just the overflow result is used (in cases where the overflow check is a single compare). Thanks for doing this! -Chris From sabre at nondot.org Mon Nov 9 01:12:01 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 09 Nov 2009 07:12:01 -0000 Subject: [llvm-commits] [llvm] r86525 - /llvm/trunk/lib/VMCore/Instructions.cpp Message-ID: <200911090712.nA97C1pV013033@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 01:12:01 2009 New Revision: 86525 URL: http://llvm.org/viewvc/llvm-project?rev=86525&view=rev Log: make this handle redefinition of malloc with different prototype correctly. Modified: llvm/trunk/lib/VMCore/Instructions.cpp Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=86525&r1=86524&r2=86525&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Mon Nov 9 01:12:01 2009 @@ -568,8 +568,7 @@ const Type *VoidTy = Type::getVoidTy(M->getContext()); const Type *IntPtrTy = Type::getInt8PtrTy(M->getContext()); // prototype free as "void free(void*)" - Function *FreeFunc = cast(M->getOrInsertFunction("free", VoidTy, - IntPtrTy, NULL)); + Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, IntPtrTy, NULL); CallInst* Result = NULL; Value *PtrCast = Source; if (InsertBefore) { @@ -582,7 +581,8 @@ Result = CallInst::Create(FreeFunc, PtrCast, ""); } Result->setTailCall(); - Result->setCallingConv(FreeFunc->getCallingConv()); + if (Function *F = dyn_cast(FreeFunc)) + Result->setCallingConv(F->getCallingConv()); return Result; } From daniel at zuster.org Mon Nov 9 01:25:15 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 09 Nov 2009 07:25:15 -0000 Subject: [llvm-commits] [zorg] r86526 - /zorg/trunk/zorg/buildbot/builders/LLVMBuilder.py Message-ID: <200911090725.nA97PGF1013604@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Nov 9 01:25:15 2009 New Revision: 86526 URL: http://llvm.org/viewvc/llvm-project?rev=86526&view=rev Log: Add plain LLVM build factory. Added: zorg/trunk/zorg/buildbot/builders/LLVMBuilder.py Added: zorg/trunk/zorg/buildbot/builders/LLVMBuilder.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/zorg/buildbot/builders/LLVMBuilder.py?rev=86526&view=auto ============================================================================== --- zorg/trunk/zorg/buildbot/builders/LLVMBuilder.py (added) +++ zorg/trunk/zorg/buildbot/builders/LLVMBuilder.py Mon Nov 9 01:25:15 2009 @@ -0,0 +1,64 @@ +import os + +import buildbot +import buildbot.process.factory +from buildbot.steps.source import SVN +from buildbot.steps.shell import Configure, ShellCommand +from buildbot.steps.shell import WarningCountingShellCommand +from buildbot.process.properties import WithProperties + +from zorg.buildbot.commands.ClangTestCommand import ClangTestCommand + +def getLLVMBuildFactory(triple=None, clean=True, test=True, + expensive_checks=False, + jobs=1, timeout=20): + f = buildbot.process.factory.BuildFactory() + + # Determine the build directory. + f.addStep(buildbot.steps.shell.SetProperty(name="get_builddir", + command=["pwd"], + property="builddir", + description="set build dir", + workdir=".")) + + # Checkout sources. + f.addStep(SVN(name='svn-llvm', + mode='update', baseURL='http://llvm.org/svn/llvm-project/llvm/', + defaultBranch='trunk', + workdir='llvm')) + + # Force without llvm-gcc so we don't run afoul of Frontend test failures. + configure_args = ["./configure", "--without-llvmgcc", "--without-llvmgxx"] + config_name = 'Debug' + if expensive_checks: + configure_args.append('--enable-expensive-checks') + config_name += '+Checks' + if triple: + configure_args += ['--build=%s' % triple, + '--host=%s' % triple, + '--target=%s' % triple] + f.addStep(Configure(command=configure_args, + workdir='llvm', + description=['configuring',config_name], + descriptionDone=['configure',config_name])) + if clean: + f.addStep(WarningCountingShellCommand(name="clean-llvm", + command="make clean", + haltOnFailure=True, + description="cleaning llvm", + descriptionDone="clean llvm", + workdir='llvm')) + f.addStep(WarningCountingShellCommand(name="compile", + command=WithProperties("nice -n 10 make -j%s" % jobs), + haltOnFailure=True, + description="compiling llvm", + descriptionDone="compile llvm", + workdir='llvm', + timeout=timeout*60)) + if test: + f.addStep(ClangTestCommand(name='test-llvm', + command=["make", "check-lit", "VERBOSE=1"], + description=["testing", "llvm"], + descriptionDone=["test", "llvm"], + workdir='llvm')) + return f From baldrick at free.fr Mon Nov 9 01:35:58 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 09 Nov 2009 08:35:58 +0100 Subject: [llvm-commits] sret-demotion for large struct returns working on x86! In-Reply-To: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> References: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> Message-ID: <4AF7C65E.4020107@free.fr> Hi Kenneth, > If a struct can't be returned in registers, have SelectionDAGBuild > insert a hidden sret parameter ... in general changing a struct returning function to use sret instead alters the calling convention, so could break ABI conformance. Presumably that's ok here because the ABI doesn't specify how to return structs that require so many registers anyway? Ciao, Duncan. From vargaz at gmail.com Mon Nov 9 01:39:38 2009 From: vargaz at gmail.com (Zoltan Varga) Date: Mon, 9 Nov 2009 08:39:38 +0100 Subject: [llvm-commits] [PATH] Implement generation of dwarf unwind info on ARM ELF Message-ID: <295e750a0911082339p3428e9m3529e903f0bccf4e@mail.gmail.com> Hi, The attached patch implements the generation of DWARF unwind info on ARM. It is currently only enabled on ELF platforms when -unwind-tables is passed to llc. I tested with manually by examining the output of objdump -W. Please review and commit if it looks ok. Zoltan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091109/b5e017e2/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-arm-unwind.diff Type: text/x-diff Size: 8224 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091109/b5e017e2/attachment.bin From daniel at zuster.org Mon Nov 9 02:07:40 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 09 Nov 2009 08:07:40 -0000 Subject: [llvm-commits] [zorg] r86530 - /zorg/trunk/zorg/buildbot/builders/LLVMGCCBuilder.py Message-ID: <200911090807.nA987eVb015474@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Nov 9 02:07:40 2009 New Revision: 86530 URL: http://llvm.org/viewvc/llvm-project?rev=86530&view=rev Log: Parameterize LLVM stage 1 and 2 build configs. Also, switch to Release as the default for both stage 1 and stage 2. A stage 2 LLVM Release build is *really* slow if the llvm-gcc was built with a Debug LLVM. Modified: zorg/trunk/zorg/buildbot/builders/LLVMGCCBuilder.py Modified: zorg/trunk/zorg/buildbot/builders/LLVMGCCBuilder.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/zorg/buildbot/builders/LLVMGCCBuilder.py?rev=86530&r1=86529&r2=86530&view=diff ============================================================================== --- zorg/trunk/zorg/buildbot/builders/LLVMGCCBuilder.py (original) +++ zorg/trunk/zorg/buildbot/builders/LLVMGCCBuilder.py Mon Nov 9 02:07:40 2009 @@ -6,9 +6,34 @@ from zorg.buildbot.commands.ClangTestCommand import ClangTestCommand +def getConfigArgs(origname): + name = origname + args = [] + if name.startswith('Release'): + name = name[len('Release'):] + args.append('--enable-optimized') + elif name.startswith('Debug'): + name = name[len('Debug'):] + else: + raise ValueError,'Unknown config name: %r' % origname + + if name.startswith('-Asserts'): + name = name[len('-Asserts'):] + args.append('--disable-assertions') + + if name.startswith('+Checks'): + name = name[len('+Checks'):] + args.append('--enable-expensive-checks') + + if name: + raise ValueError,'Unknown config name: %r' % origname + + return args + def getLLVMGCCBuildFactory(jobs=1, update=True, clean=True, gxxincludedir=None, triple=None, - useTwoStage=True): + useTwoStage=True, stage1_config='Release', + stage2_config='Release'): f = buildbot.process.factory.BuildFactory() # Determine the build directory. @@ -45,13 +70,16 @@ base_llvm_configure_args.append('--build=' + triple) base_llvm_configure_args.append('--host=' + triple) base_llvm_configure_args.append('--target=' + triple) + stage_configure_args = getConfigArgs(stage1_config) f.addStep(Configure(name='configure.llvm.stage1', - command=base_llvm_configure_args + + command=base_llvm_configure_args + + stage_configure_args + ["--without-llvmgcc", "--without-llvmgxx"], description=["configure", "llvm", - "(stage 1)"], + "(stage 1)", + stage1_config], workdir="llvm.obj")) # Build llvm (stage 1). @@ -61,7 +89,7 @@ description=["compile", "llvm", "(stage 1)", - "Debug"], + stage1_config], workdir="llvm.obj")) # Run LLVM tests (stage 1). @@ -140,10 +168,11 @@ workdir=".")) # Configure llvm (stage 2). + stage_configure_args = getConfigArgs(stage2_config) f.addStep(Configure(name="configure.llvm.stage2", command=base_llvm_configure_args + - ["--enable-optimized", - WithProperties("--with-llvmgcc=%(builddir)s/llvm-gcc.install/bin/llvm-gcc"), + stage_configure_args + + [WithProperties("--with-llvmgcc=%(builddir)s/llvm-gcc.install/bin/llvm-gcc"), WithProperties("--with-llvmgxx=%(builddir)s/llvm-gcc.install/bin/llvm-g++")], env={'CC' : WithProperties("%(builddir)s/llvm-gcc.install/bin/llvm-gcc"), 'CXX' : WithProperties("%(builddir)s/llvm-gcc.install/bin/llvm-g++"),}, @@ -152,7 +181,7 @@ description=["configure", "llvm", "(stage 2)", - "Release"])) + stage2_config])) # Build LLVM (stage 2). f.addStep(WarningCountingShellCommand(name = "compile.llvm.stage2", @@ -161,7 +190,7 @@ description=["compile", "llvm", "(stage 2)", - "Release"], + stage2_config], workdir="llvm.obj.2")) # Run LLVM tests (stage 2). From baldrick at free.fr Mon Nov 9 02:10:45 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 09 Nov 2009 08:10:45 -0000 Subject: [llvm-commits] [dragonegg] r86531 - /dragonegg/trunk/llvm-types.cpp Message-ID: <200911090810.nA98Aj7n015574@zion.cs.uiuc.edu> Author: baldrick Date: Mon Nov 9 02:10:45 2009 New Revision: 86531 URL: http://llvm.org/viewvc/llvm-project?rev=86531&view=rev Log: Fix build after header include changes in LLVM. Modified: dragonegg/trunk/llvm-types.cpp Modified: dragonegg/trunk/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-types.cpp?rev=86531&r1=86530&r2=86531&view=diff ============================================================================== --- dragonegg/trunk/llvm-types.cpp (original) +++ dragonegg/trunk/llvm-types.cpp Mon Nov 9 02:10:45 2009 @@ -35,6 +35,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/ErrorHandling.h" // System headers #include From arplynn at gmail.com Mon Nov 9 04:09:41 2009 From: arplynn at gmail.com (Alastair Lynn) Date: Mon, 9 Nov 2009 10:09:41 +0000 Subject: [llvm-commits] Patch: instcombine on overflow intrinsics Message-ID: <9BC71E21-928E-4502-A49B-6798A580C0C3@gmail.com> Hello- This patch adds the follow to instcombine: overflow intrinsic (undef, X) or overflow intrinsic (X, undef) -> undef add overflow (X, 0) or add overflow (0, X) -> {X, false} unsigned add overflow (X, Y) -> {X + Y, true} where the HO bit is provably 1 in both X and Y unsigned add overflow (X, Y) -> {X + Y, false} where the HO bit is provably 0 in both X and Y sub overflow (X, 0) -> {X, false} mul overflow (X, 0) -> {0, false} mul overflow (X, 1) -> {X, false} Testcase in patch. -------------- next part -------------- A non-text attachment was scrubbed... Name: overflow-instcombine.patch Type: application/octet-stream Size: 9868 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091109/c86211dc/attachment.obj -------------- next part -------------- From xerxes at zafena.se Mon Nov 9 04:13:55 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Mon, 09 Nov 2009 11:13:55 +0100 Subject: [llvm-commits] [patch] Make it possible to enable and disable JIT debug dumps dynamically - namespace fix for new api In-Reply-To: <9906A857-F576-4D30-95AD-6DD0578D127A@apple.com> References: <4AE8685D.2040409@zafena.se> <9906A857-F576-4D30-95AD-6DD0578D127A@apple.com> Message-ID: <4AF7EB63.8090505@zafena.se> Chris Lattner skrev: > > On Oct 28, 2009, at 8:50 AM, Xerxes R?nby wrote: > >> This patch would enable projects that use the LLVM JIT to enable and >> disable JIT debug dumps dynamically. >> The patch have been up for discussion on the llvm-dev mailinglist but >> since it have gotten no attention there im posting it for review here >> instead. >> >> http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-January/019661.html >> http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-May/022101.html >> >> Projects like Icedtea (OpenJDK) that uses the LLVM JIT would benefit >> from this patch since it would enable us to turn on dumping of JITed >> machinecode for selected methods. >> >> Patch made by Andrew Haley. > > Hi Xerxes, > > I spoke with Andrew on IRC and added a new API to do this: > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20091026/089863.html > > > Please verify that it works for you guys, > > -Chris > Hi Chris, The new API worked as expected except one small issue, I had to make SetCurrentDebugType part of the llvm namespace in Debug.cpp so that it matches Debug.h or else i get a linking error stating that llvm::SetCurrentDebugType could not get resolved. Ok to push? Cheers Xerxes -------------- next part -------------- A non-text attachment was scrubbed... Name: support_debug_namespace_llvm_SetCurrentDebugType.patch Type: text/x-patch Size: 511 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091109/d787e5a2/attachment.bin From baldrick at free.fr Mon Nov 9 04:47:58 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 09 Nov 2009 11:47:58 +0100 Subject: [llvm-commits] Patch: instcombine on overflow intrinsics In-Reply-To: <9BC71E21-928E-4502-A49B-6798A580C0C3@gmail.com> References: <9BC71E21-928E-4502-A49B-6798A580C0C3@gmail.com> Message-ID: <4AF7F35E.2090404@free.fr> Hi Alastair, > This patch adds the follow to instcombine: > overflow intrinsic (undef, X) or overflow intrinsic (X, undef) -> undef > add overflow (X, 0) or add overflow (0, X) -> {X, false} > unsigned add overflow (X, Y) -> {X + Y, true} where the HO bit is > provably 1 in both X and Y > unsigned add overflow (X, Y) -> {X + Y, false} where the HO bit is > provably 0 in both X and Y > sub overflow (X, 0) -> {X, false} > mul overflow (X, 0) -> {0, false} > mul overflow (X, 1) -> {X, false} how about deleting the overflow intrinsics instead, and add IRBuilder helper methods for generating "add with overflow" etc that generate the appropriate apint arithmetic? That way you should get all these optimizations for free, and you won't have to redo a huge chunk of integer optimizations. It may be that codegen doesn't produce optimal code for the apint versions, but in that case it's probably best to improve codegen. Ciao, Duncan. From rafael.espindola at gmail.com Mon Nov 9 08:27:04 2009 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Mon, 09 Nov 2009 14:27:04 -0000 Subject: [llvm-commits] [compiler-rt] r86542 - /compiler-rt/trunk/lib/assembly.h Message-ID: <200911091427.nA9ER4Pp014728@zion.cs.uiuc.edu> Author: rafael Date: Mon Nov 9 08:27:04 2009 New Revision: 86542 URL: http://llvm.org/viewvc/llvm-project?rev=86542&view=rev Log: Use __USER_LABEL_PREFIX__ so that we don't add a _ prefix on ELF. Modified: compiler-rt/trunk/lib/assembly.h Modified: compiler-rt/trunk/lib/assembly.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/assembly.h?rev=86542&r1=86541&r2=86542&view=diff ============================================================================== --- compiler-rt/trunk/lib/assembly.h (original) +++ compiler-rt/trunk/lib/assembly.h Mon Nov 9 08:27:04 2009 @@ -25,7 +25,7 @@ #else -#define SYMBOL_NAME(name) _##name +#define SYMBOL_NAME(name) #__USER_LABEL_PREFIX__ ##name #define SEPARATOR ; #endif From bruno.cardoso at gmail.com Mon Nov 9 08:27:49 2009 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Mon, 09 Nov 2009 14:27:49 -0000 Subject: [llvm-commits] [llvm] r86543 - in /llvm/trunk/lib/Target/Mips: MipsMachineFunction.h MipsRegisterInfo.cpp Message-ID: <200911091427.nA9ERnbk014775@zion.cs.uiuc.edu> Author: bruno Date: Mon Nov 9 08:27:49 2009 New Revision: 86543 URL: http://llvm.org/viewvc/llvm-project?rev=86543&view=rev Log: Fix PR5149. http://llvm.org/bugs/show_bug.cgi?id=5149 Modified: llvm/trunk/lib/Target/Mips/MipsMachineFunction.h llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp Modified: llvm/trunk/lib/Target/Mips/MipsMachineFunction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsMachineFunction.h?rev=86543&r1=86542&r2=86543&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsMachineFunction.h (original) +++ llvm/trunk/lib/Target/Mips/MipsMachineFunction.h Mon Nov 9 08:27:49 2009 @@ -103,6 +103,7 @@ int getGPFI() const { return GPHolder.FI; } void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; } void setGPFI(int FI) { GPHolder.FI = FI; } + bool needGPSaveRestore() const { return GPHolder.SPOffset != -1; } bool hasLoadArgs() const { return HasLoadArgs; } bool hasStoreVarArgs() const { return HasStoreVarArgs; } Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp?rev=86543&r1=86542&r2=86543&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp Mon Nov 9 08:27:49 2009 @@ -438,11 +438,10 @@ .addReg(Mips::SP).addReg(Mips::ZERO); } - // PIC speficic function prologue - if ((isPIC) && (MFI->hasCalls())) { + // Restore GP from the saved stack location + if (MipsFI->needGPSaveRestore()) BuildMI(MBB, MBBI, dl, TII.get(Mips::CPRESTORE)) .addImm(MipsFI->getGPStackOffset()); - } } void MipsRegisterInfo:: @@ -489,13 +488,11 @@ void MipsRegisterInfo:: processFunctionBeforeFrameFinalized(MachineFunction &MF) const { - // Set the SPOffset on the FI where GP must be saved/loaded. + // Set the stack offset where GP must be saved/loaded from. MachineFrameInfo *MFI = MF.getFrameInfo(); - bool isPIC = (MF.getTarget().getRelocationModel() == Reloc::PIC_); - if (MFI->hasCalls() && isPIC) { - MipsFunctionInfo *MipsFI = MF.getInfo(); + MipsFunctionInfo *MipsFI = MF.getInfo(); + if (MipsFI->needGPSaveRestore()) MFI->setObjectOffset(MipsFI->getGPFI(), MipsFI->getGPStackOffset()); - } } unsigned MipsRegisterInfo:: From xerxes at zafena.se Mon Nov 9 08:50:35 2009 From: xerxes at zafena.se (Xerxes Ranby) Date: Mon, 09 Nov 2009 14:50:35 -0000 Subject: [llvm-commits] [llvm] r86544 - /llvm/trunk/lib/Support/Debug.cpp Message-ID: <200911091450.nA9EoZxM015594@zion.cs.uiuc.edu> Author: xranby Date: Mon Nov 9 08:50:34 2009 New Revision: 86544 URL: http://llvm.org/viewvc/llvm-project?rev=86544&view=rev Log: Make lib/Support/Debug.cpp SetCurrentDebugType implementation part of llvm namespace to match function declaration in Debug.h. Modified: llvm/trunk/lib/Support/Debug.cpp Modified: llvm/trunk/lib/Support/Debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Debug.cpp?rev=86544&r1=86543&r2=86544&view=diff ============================================================================== --- llvm/trunk/lib/Support/Debug.cpp (original) +++ llvm/trunk/lib/Support/Debug.cpp Mon Nov 9 08:50:34 2009 @@ -62,7 +62,7 @@ /// option were specified. Note that DebugFlag also needs to be set to true for /// debug output to be produced. /// -void SetCurrentDebugType(const char *Type) { +void llvm::SetCurrentDebugType(const char *Type) { CurrentDebugType = Type; } From xerxes at zafena.se Mon Nov 9 08:53:52 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Mon, 09 Nov 2009 15:53:52 +0100 Subject: [llvm-commits] [patch] Make it possible to enable and disable JIT debug dumps dynamically - namespace fix for new api In-Reply-To: <4AF7EB63.8090505@zafena.se> References: <4AE8685D.2040409@zafena.se> <9906A857-F576-4D30-95AD-6DD0578D127A@apple.com> <4AF7EB63.8090505@zafena.se> Message-ID: <4AF82D00.3070307@zafena.se> I have commited the small namespace fix for this new API in: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20091109/090686.html Cheers, and have a great day! Xerxes Xerxes R?nby skrev: > Chris Lattner skrev: > >> On Oct 28, 2009, at 8:50 AM, Xerxes R?nby wrote: >> >> >>> This patch would enable projects that use the LLVM JIT to enable and >>> disable JIT debug dumps dynamically. >>> The patch have been up for discussion on the llvm-dev mailinglist but >>> since it have gotten no attention there im posting it for review here >>> instead. >>> >>> http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-January/019661.html >>> http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-May/022101.html >>> >>> Projects like Icedtea (OpenJDK) that uses the LLVM JIT would benefit >>> from this patch since it would enable us to turn on dumping of JITed >>> machinecode for selected methods. >>> >>> Patch made by Andrew Haley. >>> >> Hi Xerxes, >> >> I spoke with Andrew on IRC and added a new API to do this: >> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20091026/089863.html >> >> >> Please verify that it works for you guys, >> >> -Chris >> >> > Hi Chris, > > The new API worked as expected except one small issue, I had to make > SetCurrentDebugType part of the llvm namespace in Debug.cpp so that it > matches Debug.h or else i get a linking error stating that > llvm::SetCurrentDebugType could not get resolved. > > Ok to push? > > Cheers > Xerxes > > ------------------------------------------------------------------------ > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From ofv at wanadoo.es Mon Nov 9 09:26:43 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Mon, 09 Nov 2009 15:26:43 -0000 Subject: [llvm-commits] [llvm] r86547 - in /llvm/trunk: cmake/config-ix.cmake include/llvm/Config/config.h.cmake Message-ID: <200911091526.nA9FQhRr016776@zion.cs.uiuc.edu> Author: ofv Date: Mon Nov 9 09:26:40 2009 New Revision: 86547 URL: http://llvm.org/viewvc/llvm-project?rev=86547&view=rev Log: CMake: Detect gv, circo, twopi, neato, fdo, dot and dotty. Patch by Arnaud Allard de Grandmaison! Modified: llvm/trunk/cmake/config-ix.cmake llvm/trunk/include/llvm/Config/config.h.cmake Modified: llvm/trunk/cmake/config-ix.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=86547&r1=86546&r2=86547&view=diff ============================================================================== --- llvm/trunk/cmake/config-ix.cmake (original) +++ llvm/trunk/cmake/config-ix.cmake Mon Nov 9 09:26:40 2009 @@ -127,13 +127,26 @@ check_type_exists(u_int64_t "${headers}" HAVE_U_INT64_T) # available programs checks -find_program(DOTTY_EXECUTABLE dotty) -if(DOTTY_EXECUTABLE) - set(HAVE_DOTTY 1) - set(LLVM_PATH_DOTTY ${DOTTY_EXECUTABLE}) - mark_as_advanced(HAVE_DOTTY) - mark_as_advanced(LLVM_PATH_DOTTY) -endif() +function(llvm_find_program name) + string(TOUPPER ${name} NAME) + find_program(LLVM_PATH_${NAME} ${name}) + mark_as_advanced(LLVM_PATH_${NAME}) + if(LLVM_PATH_${NAME}) + set(HAVE_${NAME} 1 CACHE INTERNAL "Is ${name} available ?") + mark_as_advanced(HAVE_${NAME}) + else(LLVM_PATH_${NAME}) + set(HAVE_${NAME} "" CACHE INTERNAL "Is ${name} available ?") + unset(LLVM_PATH_${NAME} CACHE) + endif(LLVM_PATH_${NAME}) +endfunction() + +llvm_find_program(gv) +llvm_find_program(circo) +llvm_find_program(twopi) +llvm_find_program(neato) +llvm_find_program(fdp) +llvm_find_program(dot) +llvm_find_program(dotty) # Define LLVM_MULTITHREADED if gcc atomic builtins exists. include(CheckAtomic) Modified: llvm/trunk/include/llvm/Config/config.h.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Config/config.h.cmake?rev=86547&r1=86546&r2=86547&view=diff ============================================================================== --- llvm/trunk/include/llvm/Config/config.h.cmake (original) +++ llvm/trunk/include/llvm/Config/config.h.cmake Mon Nov 9 09:26:40 2009 @@ -48,6 +48,9 @@ /* Define to 1 if you have the `ceilf' function. */ #cmakedefine HAVE_CEILF ${HAVE_CEILF} +/* Define if the neat program is available */ +#cmakedefine HAVE_CIRCO ${HAVE_CIRCO} + /* Define to 1 if you have the `closedir' function. */ #undef HAVE_CLOSEDIR @@ -77,7 +80,7 @@ #cmakedefine HAVE_DL_H ${HAVE_DL_H} /* Define if the dot program is available */ -#undef HAVE_DOT +#cmakedefine HAVE_DOT ${HAVE_DOT} /* Define if the dotty program is available */ #cmakedefine HAVE_DOTTY ${HAVE_DOTTY} @@ -97,6 +100,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_FCNTL_H ${HAVE_FCNTL_H} +/* Define if the neat program is available */ +#cmakedefine HAVE_FDP ${HAVE_FDP} + /* Set to 1 if the finite function is found in */ #cmakedefine HAVE_FINITE_IN_IEEEFP_H ${HAVE_FINITE_IN_IEEEFP_H} @@ -137,7 +143,7 @@ #undef HAVE_GRAPHVIZ /* Define if the gv program is available */ -#undef HAVE_GV +#cmakedefine HAVE_GV ${HAVE_GV} /* Define to 1 if you have the `index' function. */ #undef HAVE_INDEX @@ -249,6 +255,9 @@ /* Define to 1 if you have the `nearbyintf' function. */ #undef HAVE_NEARBYINTF +/* Define if the neat program is available */ +#cmakedefine HAVE_NEATO ${HAVE_NEATO} + /* Define to 1 if you have the `opendir' function. */ #undef HAVE_OPENDIR @@ -410,6 +419,9 @@ /* Define to 1 if you have that is POSIX.1 compatible. */ #cmakedefine HAVE_SYS_WAIT_H ${HAVE_SYS_WAIT_H} +/* Define if the neat program is available */ +#cmakedefine HAVE_TWOPI ${HAVE_TWOPI} + /* Define to 1 if the system has the type `uint64_t'. */ #undef HAVE_UINT64_T @@ -467,17 +479,29 @@ /* Added by Kevin -- Maximum path length */ #cmakedefine MAXPATHLEN ${MAXPATHLEN} +/* Define to path to circo program if found or 'echo circo' otherwise */ +#cmakedefine LLVM_PATH_CIRCO "${LLVM_PATH_CIRCO}" + /* Define to path to dot program if found or 'echo dot' otherwise */ -#undef LLVM_PATH_DOT +#cmakedefine LLVM_PATH_DOT "${LLVM_PATH_DOT}" /* Define to path to dotty program if found or 'echo dotty' otherwise */ #cmakedefine LLVM_PATH_DOTTY "${LLVM_PATH_DOTTY}" +/* Define to path to fdp program if found or 'echo fdp' otherwise */ +#cmakedefine LLVM_PATH_FDP "${LLVM_PATH_FDP}" + /* Define to path to Graphviz program if found or 'echo Graphviz' otherwise */ #undef LLVM_PATH_GRAPHVIZ /* Define to path to gv program if found or 'echo gv' otherwise */ -#undef LLVM_PATH_GV +#cmakedefine LLVM_PATH_GV "${LLVM_PATH_GV}" + +/* Define to path to neato program if found or 'echo neato' otherwise */ +#cmakedefine LLVM_PATH_NEATO "${LLVM_PATH_NEATO}" + +/* Define to path to twopi program if found or 'echo twopi' otherwise */ +#cmakedefine LLVM_PATH_TWOPI "${LLVM_PATH_TWOPI}" /* Installation prefix directory */ #undef LLVM_PREFIX From grosbach at apple.com Mon Nov 9 09:27:51 2009 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 09 Nov 2009 15:27:51 -0000 Subject: [llvm-commits] [llvm] r86548 - /llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Message-ID: <200911091527.nA9FRprg016845@zion.cs.uiuc.edu> Author: grosbach Date: Mon Nov 9 09:27:51 2009 New Revision: 86548 URL: http://llvm.org/viewvc/llvm-project?rev=86548&view=rev Log: Work around assembler not recognizing #0.0 form immediate for vmcp Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=86548&r1=86547&r2=86548&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Mon Nov 9 09:27:51 2009 @@ -194,11 +194,11 @@ let Defs = [FPSCR] in { def VCMPEZD : ADuI<0b11101011, 0b0101, 0b1100, (outs), (ins DPR:$a), - IIC_fpCMP64, "vcmpe", ".f64\t$a, #0.0", + IIC_fpCMP64, "vcmpe", ".f64\t$a, #0", [(arm_cmpfp0 DPR:$a)]>; def VCMPEZS : ASuI<0b11101011, 0b0101, 0b1100, (outs), (ins SPR:$a), - IIC_fpCMP32, "vcmpe", ".f32\t$a, #0.0", + IIC_fpCMP32, "vcmpe", ".f32\t$a, #0", [(arm_cmpfp0 SPR:$a)]>; } From nunoplopes at sapo.pt Mon Nov 9 09:36:28 2009 From: nunoplopes at sapo.pt (Nuno Lopes) Date: Mon, 09 Nov 2009 15:36:28 -0000 Subject: [llvm-commits] [llvm] r86549 - in /llvm/trunk: include/llvm/Support/ConstantRange.h lib/Support/ConstantRange.cpp Message-ID: <200911091536.nA9FaSji017134@zion.cs.uiuc.edu> Author: nlopes Date: Mon Nov 9 09:36:28 2009 New Revision: 86549 URL: http://llvm.org/viewvc/llvm-project?rev=86549&view=rev Log: add zextOrTrunc and sextOrTrunc methods, that are similar to the ones in APInt Modified: llvm/trunk/include/llvm/Support/ConstantRange.h llvm/trunk/lib/Support/ConstantRange.cpp Modified: llvm/trunk/include/llvm/Support/ConstantRange.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ConstantRange.h?rev=86549&r1=86548&r2=86549&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/ConstantRange.h (original) +++ llvm/trunk/include/llvm/Support/ConstantRange.h Mon Nov 9 09:36:28 2009 @@ -187,6 +187,14 @@ /// truncated to the specified type. ConstantRange truncate(uint32_t BitWidth) const; + /// zextOrTrunc - make this range have the bit width given by \p BitWidth. The + /// value is zero extended, truncated, or left alone to make it that width. + ConstantRange zextOrTrunc(uint32_t BitWidth) const; + + /// sextOrTrunc - make this range have the bit width given by \p BitWidth. The + /// value is sign extended, truncated, or left alone to make it that width. + ConstantRange sextOrTrunc(uint32_t BitWidth) const; + /// add - Return a new range representing the possible values resulting /// from an addition of a value in this range and a value in Other. ConstantRange add(const ConstantRange &Other) const; Modified: llvm/trunk/lib/Support/ConstantRange.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ConstantRange.cpp?rev=86549&r1=86548&r2=86549&view=diff ============================================================================== --- llvm/trunk/lib/Support/ConstantRange.cpp (original) +++ llvm/trunk/lib/Support/ConstantRange.cpp Mon Nov 9 09:36:28 2009 @@ -492,6 +492,30 @@ return ConstantRange(L, U); } +/// zextOrTrunc - make this range have the bit width given by \p DstTySize. The +/// value is zero extended, truncated, or left alone to make it that width. +ConstantRange ConstantRange::zextOrTrunc(uint32_t DstTySize) const { + unsigned SrcTySize = getBitWidth(); + if (SrcTySize > DstTySize) + return truncate(DstTySize); + else if (SrcTySize < DstTySize) + return zeroExtend(DstTySize); + else + return *this; +} + +/// sextOrTrunc - make this range have the bit width given by \p DstTySize. The +/// value is sign extended, truncated, or left alone to make it that width. +ConstantRange ConstantRange::sextOrTrunc(uint32_t DstTySize) const { + unsigned SrcTySize = getBitWidth(); + if (SrcTySize > DstTySize) + return truncate(DstTySize); + else if (SrcTySize < DstTySize) + return signExtend(DstTySize); + else + return *this; +} + ConstantRange ConstantRange::add(const ConstantRange &Other) const { if (isEmptySet() || Other.isEmptySet()) From baldrick at free.fr Mon Nov 9 10:32:02 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 09 Nov 2009 17:32:02 +0100 Subject: [llvm-commits] sret-demotion for large struct returns working on x86! In-Reply-To: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> References: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> Message-ID: <4AF84402.1070300@free.fr> Hi Kenneth, > + // True if the function needs to be sret-demoted > + bool CantLowerReturn; rather than using a negative, how about CanLowerReturn? > + /// getCantLowerReturn - Return true if the function needs sret-demotion. The name exposes the implementation (accessing an internal variable called CantLowerReturn) rather than the logical function. How about negating it and calling it "canLowerReturn". > + bool CanLowerReturn = TLI.CanLowerReturn(CS.getCallingConv(), > + FTy->isVarArg(), OutVTs, OutsFlags, DAG); Isn't it confusing to have several Can/Cant's. What's the connection between them? I'm not competent to comment on the rest of the patch. Ciao, Duncan. From daniel at zuster.org Mon Nov 9 10:38:16 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 09 Nov 2009 16:38:16 -0000 Subject: [llvm-commits] [llvm] r86553 - in /llvm/trunk/test: FrontendC++/2006-11-06-StackTrace.cpp FrontendC++/2006-11-30-NoCompileUnit.cpp FrontendC++/2006-11-30-Pubnames.cpp FrontendC/Atomics-no64bit.c FrontendC/Atomics.c Message-ID: <200911091638.nA9GcGWO019586@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Nov 9 10:38:15 2009 New Revision: 86553 URL: http://llvm.org/viewvc/llvm-project?rev=86553&view=rev Log: Use ',' separation in XFAILs, lit doesn't evaluate them as regexs (easy to add, but might as well use the more standard syntax). Modified: llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp llvm/trunk/test/FrontendC++/2006-11-30-NoCompileUnit.cpp llvm/trunk/test/FrontendC++/2006-11-30-Pubnames.cpp llvm/trunk/test/FrontendC/Atomics-no64bit.c llvm/trunk/test/FrontendC/Atomics.c Modified: llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC%2B%2B/2006-11-06-StackTrace.cpp?rev=86553&r1=86552&r2=86553&view=diff ============================================================================== --- llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp (original) +++ llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp Mon Nov 9 10:38:15 2009 @@ -12,7 +12,7 @@ // Only works on ppc (but not apple-darwin9), x86 and x86_64. Should // generalize? -// XFAIL: alpha|arm|powerpc-apple-darwin9 +// XFAIL: alpha,arm,powerpc-apple-darwin9 #include Modified: llvm/trunk/test/FrontendC++/2006-11-30-NoCompileUnit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC%2B%2B/2006-11-30-NoCompileUnit.cpp?rev=86553&r1=86552&r2=86553&view=diff ============================================================================== --- llvm/trunk/test/FrontendC++/2006-11-30-NoCompileUnit.cpp (original) +++ llvm/trunk/test/FrontendC++/2006-11-30-NoCompileUnit.cpp Mon Nov 9 10:38:15 2009 @@ -7,7 +7,7 @@ // RUN: echo {break main\nrun\np NoCompileUnit::pubname} > %t2 // RUN: gdb -q -batch -n -x %t2 NoCompileUnit.exe | \ // RUN: tee NoCompileUnit.out | not grep {"low == high"} -// XFAIL: alpha|arm +// XFAIL: alpha,arm // XFAIL: * // See PR2454 Modified: llvm/trunk/test/FrontendC++/2006-11-30-Pubnames.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC%2B%2B/2006-11-30-Pubnames.cpp?rev=86553&r1=86552&r2=86553&view=diff ============================================================================== --- llvm/trunk/test/FrontendC++/2006-11-30-Pubnames.cpp (original) +++ llvm/trunk/test/FrontendC++/2006-11-30-Pubnames.cpp Mon Nov 9 10:38:15 2009 @@ -7,7 +7,7 @@ // RUN: %llvmdsymutil %t.exe // RUN: echo {break main\nrun\np Pubnames::pubname} > %t.in // RUN: gdb -q -batch -n -x %t.in %t.exe | tee %t.out | grep {\$1 = 10} -// XFAIL: alpha|arm +// XFAIL: alpha,arm struct Pubnames { static int pubname; }; Modified: llvm/trunk/test/FrontendC/Atomics-no64bit.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC/Atomics-no64bit.c?rev=86553&r1=86552&r2=86553&view=diff ============================================================================== --- llvm/trunk/test/FrontendC/Atomics-no64bit.c (original) +++ llvm/trunk/test/FrontendC/Atomics-no64bit.c Mon Nov 9 10:38:15 2009 @@ -9,7 +9,7 @@ // Currently this is implemented only for Alpha, X86, PowerPC. // Add your target here if it doesn't work. // This version of the test does not include long long. -// XFAIL: sparc|arm +// XFAIL: sparc,arm signed char sc; unsigned char uc; Modified: llvm/trunk/test/FrontendC/Atomics.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC/Atomics.c?rev=86553&r1=86552&r2=86553&view=diff ============================================================================== --- llvm/trunk/test/FrontendC/Atomics.c (original) +++ llvm/trunk/test/FrontendC/Atomics.c Mon Nov 9 10:38:15 2009 @@ -9,7 +9,7 @@ // Currently this is implemented only for Alpha, X86, PowerPC. // Add your target here if it doesn't work. // PPC32 does not translate the long long variants, so fails this test. -// XFAIL: sparc|arm|powerpc +// XFAIL: sparc,arm,powerpc signed char sc; unsigned char uc; From kennethuil at gmail.com Mon Nov 9 10:44:20 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Mon, 9 Nov 2009 10:44:20 -0600 Subject: [llvm-commits] sret-demotion for large struct returns working on x86! In-Reply-To: <4AF84402.1070300@free.fr> References: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> <4AF84402.1070300@free.fr> Message-ID: <400d33ea0911090844p6b465da5l1b9b228a8c36beb1@mail.gmail.com> On Mon, Nov 9, 2009 at 10:32 AM, Duncan Sands wrote: > Hi Kenneth, > >> + ?// True if the function needs to be sret-demoted >> + ?bool CantLowerReturn; > > rather than using a negative, how about CanLowerReturn? I had the notion that we usually tried to default flags to false. > >> + ?/// getCantLowerReturn - Return true if the function needs >> sret-demotion. > > The name exposes the implementation (accessing an internal variable called > CantLowerReturn) rather than the logical function. ?How about negating it > and > calling it "canLowerReturn". Excellent idea. I'll do that. > >> + ?bool CanLowerReturn = TLI.CanLowerReturn(CS.getCallingConv(), + >> ? ? ? ? ? ? ? ?FTy->isVarArg(), OutVTs, OutsFlags, DAG); > > Isn't it confusing to have several Can/Cant's. ?What's the connection > between > them? TargetLowering::CanLowerReturn checks lowerability against the target implementation of the calling convention. In SelectionDAGISel::LowerArguments, I'm calling TargetLowering::CanLowerReturn once, then stashing that information (along with a virtual reg to hold the inserted sret parameter, if CanLowerReturn returns false) in the MachineFunction (the CantLowerReturn flag and the DemoteRegister field) so I don't have to keep calling CanLowerReturn each time I hit a return instruction (handled by SelectionDAGLowering::visitRet) in that same function. I'm assuming, of course, that (a) LowerFormalArguments always gets called before visitRet and (b) the same MachineFunction instance always comes back whenever visitXXX or LowerXXX is called to process code within the same function. If either assumption is bogus, then my code is broken. From gohman at apple.com Mon Nov 9 11:06:24 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 09 Nov 2009 17:06:24 -0000 Subject: [llvm-commits] [llvm] r86557 - /llvm/trunk/include/llvm/CodeGen/MachineFunction.h Message-ID: <200911091706.nA9H6OpJ020714@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 11:06:23 2009 New Revision: 86557 URL: http://llvm.org/viewvc/llvm-project?rev=86557&view=rev Log: Suppress implicit copy ctor and copy assignment for MachineFunction. Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunction.h?rev=86557&r1=86556&r2=86557&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFunction.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineFunction.h Mon Nov 9 11:06:23 2009 @@ -115,6 +115,9 @@ // The alignment of the function. unsigned Alignment; + MachineFunction(const MachineFunction &); // intentionally unimplemented + void operator=(const MachineFunction&); // intentionally unimplemented + public: MachineFunction(Function *Fn, const TargetMachine &TM); ~MachineFunction(); From gohman at apple.com Mon Nov 9 11:06:52 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 09 Nov 2009 17:06:52 -0000 Subject: [llvm-commits] [llvm] r86558 - /llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Message-ID: <200911091706.nA9H6qLN020735@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 11:06:51 2009 New Revision: 86558 URL: http://llvm.org/viewvc/llvm-project?rev=86558&view=rev Log: Fix a comment. Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=86558&r1=86557&r2=86558&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Mon Nov 9 11:06:51 2009 @@ -246,7 +246,7 @@ /// transferSuccessors - Transfers all the successors from MBB to this /// machine basic block (i.e., copies all the successors fromMBB and - /// remove all the successors fromBB). + /// remove all the successors from fromMBB). void transferSuccessors(MachineBasicBlock *fromMBB); /// isSuccessor - Return true if the specified MBB is a successor of this From gohman at apple.com Mon Nov 9 12:18:49 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 09 Nov 2009 18:18:49 -0000 Subject: [llvm-commits] [llvm] r86564 - in /llvm/trunk: include/llvm/CodeGen/MachineFunctionAnalysis.h lib/CodeGen/MachineFunctionAnalysis.cpp Message-ID: <200911091818.nA9IIn23023964@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 12:18:49 2009 New Revision: 86564 URL: http://llvm.org/viewvc/llvm-project?rev=86564&view=rev Log: Constify MachineFunctionAnalysis' TargetMachine reference. Modified: llvm/trunk/include/llvm/CodeGen/MachineFunctionAnalysis.h llvm/trunk/lib/CodeGen/MachineFunctionAnalysis.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineFunctionAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunctionAnalysis.h?rev=86564&r1=86563&r2=86564&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFunctionAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineFunctionAnalysis.h Mon Nov 9 12:18:49 2009 @@ -31,7 +31,7 @@ public: static char ID; - explicit MachineFunctionAnalysis(TargetMachine &tm, + explicit MachineFunctionAnalysis(const TargetMachine &tm, CodeGenOpt::Level OL = CodeGenOpt::Default); ~MachineFunctionAnalysis(); Modified: llvm/trunk/lib/CodeGen/MachineFunctionAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunctionAnalysis.cpp?rev=86564&r1=86563&r2=86564&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineFunctionAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineFunctionAnalysis.cpp Mon Nov 9 12:18:49 2009 @@ -24,7 +24,7 @@ char MachineFunctionAnalysis::ID = 0; -MachineFunctionAnalysis::MachineFunctionAnalysis(TargetMachine &tm, +MachineFunctionAnalysis::MachineFunctionAnalysis(const TargetMachine &tm, CodeGenOpt::Level OL) : FunctionPass(&ID), TM(tm), OptLevel(OL), MF(0) { } From gohman at apple.com Mon Nov 9 12:19:43 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 09 Nov 2009 18:19:43 -0000 Subject: [llvm-commits] [llvm] r86565 - /llvm/trunk/lib/Analysis/LoopInfo.cpp Message-ID: <200911091819.nA9IJiA6024004@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 12:19:43 2009 New Revision: 86565 URL: http://llvm.org/viewvc/llvm-project?rev=86565&view=rev Log: Minor tidiness fixes. Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopInfo.cpp?rev=86565&r1=86564&r2=86565&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LoopInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LoopInfo.cpp Mon Nov 9 12:19:43 2009 @@ -263,14 +263,13 @@ SmallPtrSet LoopBBs(block_begin(), block_end()); for (block_iterator BI = block_begin(), E = block_end(); BI != E; ++BI) { - BasicBlock *BB = *BI; - for (BasicBlock ::iterator I = BB->begin(), E = BB->end(); I != E;++I) + BasicBlock *BB = *BI; + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;++I) for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) { BasicBlock *UserBB = cast(*UI)->getParent(); - if (PHINode *P = dyn_cast(*UI)) { + if (PHINode *P = dyn_cast(*UI)) UserBB = P->getIncomingBlock(UI); - } // Check the current block, as a fast-path. Most values are used in // the same block they are defined in. From gohman at apple.com Mon Nov 9 12:20:38 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 09 Nov 2009 18:20:38 -0000 Subject: [llvm-commits] [llvm] r86567 - /llvm/trunk/include/llvm/Analysis/LoopInfo.h Message-ID: <200911091820.nA9IKcOx024057@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 12:20:38 2009 New Revision: 86567 URL: http://llvm.org/viewvc/llvm-project?rev=86567&view=rev Log: Fix an 80-column violation. Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=86567&r1=86566&r2=86567&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Mon Nov 9 12:20:38 2009 @@ -114,8 +114,8 @@ block_iterator block_begin() const { return Blocks.begin(); } block_iterator block_end() const { return Blocks.end(); } - /// isLoopExiting - True if terminator in the block can branch to another block - /// that is outside of the current loop. + /// isLoopExiting - True if terminator in the block can branch to another + /// block that is outside of the current loop. /// bool isLoopExiting(const BlockT *BB) const { typedef GraphTraits BlockTraits; From gohman at apple.com Mon Nov 9 12:28:24 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 09 Nov 2009 18:28:24 -0000 Subject: [llvm-commits] [llvm] r86569 - in /llvm/trunk: lib/Transforms/Utils/LCSSA.cpp test/Transforms/LCSSA/indirectbr.ll Message-ID: <200911091828.nA9ISOw3024412@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 12:28:24 2009 New Revision: 86569 URL: http://llvm.org/viewvc/llvm-project?rev=86569&view=rev Log: Generalize LCSSA to handle loops with exits with predecessors outside the loop. This is needed because with indirectbr it may not be possible for LoopSimplify to guarantee that all loop exit predecessors are inside the loop. This fixes PR5437. LCCSA no longer actually requires LoopSimplify form, but for now it must still have the dependency because the PassManager doesn't know how to schedule LoopSimplify otherwise. Added: llvm/trunk/test/Transforms/LCSSA/indirectbr.ll Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LCSSA.cpp?rev=86569&r1=86568&r2=86569&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LCSSA.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Mon Nov 9 12:28:24 2009 @@ -63,6 +63,9 @@ /// virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); + + // LCSSA doesn't actually require LoopSimplify, but the PassManager + // doesn't know how to schedule LoopSimplify by itself. AU.addRequiredID(LoopSimplifyID); AU.addPreservedID(LoopSimplifyID); AU.addRequiredTransitive(); @@ -214,7 +217,7 @@ SSAUpdate.Initialize(Inst); // Insert the LCSSA phi's into all of the exit blocks dominated by the - // value., and add them to the Phi's map. + // value, and add them to the Phi's map. for (SmallVectorImpl::const_iterator BBI = ExitBlocks.begin(), BBE = ExitBlocks.end(); BBI != BBE; ++BBI) { BasicBlock *ExitBB = *BBI; @@ -228,8 +231,17 @@ PN->reserveOperandSpace(PredCache.GetNumPreds(ExitBB)); // Add inputs from inside the loop for this PHI. - for (BasicBlock **PI = PredCache.GetPreds(ExitBB); *PI; ++PI) + for (BasicBlock **PI = PredCache.GetPreds(ExitBB); *PI; ++PI) { PN->addIncoming(Inst, *PI); + + // If the exit block has a predecessor not within the loop, arrange for + // the incomging value use corresponding to that predecessor to be + // rewritten in terms of a different LCSSA PHI. + if (!inLoop(*PI)) + UsesToRewrite.push_back( + &PN->getOperandUse( + PN->getOperandNumForIncomingValue(PN->getNumIncomingValues()-1))); + } // Remember that this phi makes the value alive in this block. SSAUpdate.AddAvailableValue(ExitBB, PN); Added: llvm/trunk/test/Transforms/LCSSA/indirectbr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LCSSA/indirectbr.ll?rev=86569&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LCSSA/indirectbr.ll (added) +++ llvm/trunk/test/Transforms/LCSSA/indirectbr.ll Mon Nov 9 12:28:24 2009 @@ -0,0 +1,635 @@ +; RUN: opt < %s -lcssa -verify-loop-info -verify-dom-info -disable-output +; PR5437 + +; LCSSA should work correctly in the case of an indirectbr that exits +; the loop, and the loop has exits with predecessors not within the loop +; (and btw these edges are unsplittable due to the indirectbr). + +define i32 @js_Interpret() nounwind { +entry: + br i1 undef, label %"4", label %"3" + +"3": ; preds = %entry + ret i32 0 + +"4": ; preds = %entry + br i1 undef, label %"6", label %"5" + +"5": ; preds = %"4" + unreachable + +"6": ; preds = %"4" + br i1 undef, label %"10", label %"13" + +"10": ; preds = %"6" + br i1 undef, label %"22", label %"15" + +"13": ; preds = %"6" + unreachable + +"15": ; preds = %"23", %"10" + unreachable + +"22": ; preds = %"10" + br label %"23" + +"23": ; preds = %"1375", %"22" + %0 = phi i32 [ undef, %"22" ], [ %1, %"1375" ] ; [#uses=1] + indirectbr i8* undef, [label %"15", label %"24", label %"25", label %"26", label %"27", label %"28", label %"29", label %"30", label %"32", label %"32", label %"33", label %"35", label %"36", label %"41", label %"41", label %"60", label %"61", label %"65", label %"76", label %"87", label %"95", label %"103", label %"104", label %"108", label %"119", label %"130", label %"138", label %"146", label %"164", label %"162", label %"163", label %"166", label %"167", label %"173", label %"173", label %"173", label %"173", label %"173", label %"192", label %"193", label %"194", label %"196", label %"206", label %"231", label %"241", label %"251", label %"261", label %"307", label %"353", label %"354", label %"355", label %"361", label %"367", label %"400", label %"433", label %"466", label %"499", label %"509", label %"519", label %"529", label %"571", label %"589", label %"607", label %"635", label %"655", label %"664", label %"671", label %"680", label %"687", label %"692", labe! l %"698", label %"704", label %"715", label %"715", label %"716", label %"725", label %"725", label %"725", label %"725", label %"724", label %"724", label %"724", label %"724", label %"737", label %"737", label %"737", label %"737", label %"761", label %"758", label %"759", label %"760", label %"766", label %"763", label %"764", label %"765", label %"771", label %"768", label %"769", label %"770", label %"780", label %"777", label %"778", label %"779", label %"821", label %"826", label %"831", label %"832", label %"833", label %"836", label %"836", label %"886", label %"905", label %"978", label %"978", label %"1136", label %"1166", label %"1179", label %"1201", label %"1212", label %"1212", label %"1274", label %"1284", label %"1284", label %"1346", label %"1347", label %"1348", label %"1349", label %"1350", label %"1353", label %"1353", label %"1353", label %"1355", label %"1355", label %"1357", label %"1357", label %"1358", label %"1359", label %"1374", label %"1375", l! abel %"1376", label %"1377", label %"1378", label %"1379", lab! el %"138 6", label %"1395", label %"1394", label %"1425", label %"1426", label %"1440", label %"1449", label %"1455", label %"1461", label %"1471", label %"1482", label %"1484", label %"1486", label %"1489", label %"1489", label %"1492", label %"1494", label %"1494", label %"1497", label %"1499", label %"1499", label %"1515", label %"1546", label %"1546", label %"1566", label %"1584", label %"1587", label %"1591", label %"1605", label %"1609", label %"1609", label %"1640", label %"1648", label %"1651", label %"1703", label %"1710", label %"1718", label %"1724", label %"1725", label %"1726", label %"1727", label %"1728", label %"1731", label %"1732", label %"1733", label %"1734", label %"1735", label %"1741", label %"1750", label %"1752", label %"1754", label %"1755", label %"1757", label %"1759", label %"1761", label %"1764", label %"1764", label %"1766", label %"1768", label %"1775", label %"1775", label %"1781", label %"1781", label %"1790", label %"1791", label %"1801", label %"18! 02", label %"1803", label %"1805", label %"1807", label %"1809", label %"1817", label %"1819", label %"1821", label %"1823", label %"1825", label %"1827", label %"1836", label %"1836", label %"1845", label %"1845", label %"1848", label %"1849", label %"1851", label %"1853", label %"1856", label %"1861", label %"1861"] + +"24": ; preds = %"23" + unreachable + +"25": ; preds = %"23" + unreachable + +"26": ; preds = %"23" + unreachable + +"27": ; preds = %"23" + unreachable + +"28": ; preds = %"23" + unreachable + +"29": ; preds = %"23" + unreachable + +"30": ; preds = %"23" + unreachable + +"32": ; preds = %"23", %"23" + unreachable + +"33": ; preds = %"23" + unreachable + +"35": ; preds = %"23" + unreachable + +"36": ; preds = %"23" + unreachable + +"60": ; preds = %"23" + unreachable + +"61": ; preds = %"23" + unreachable + +"65": ; preds = %"23" + unreachable + +"76": ; preds = %"23" + unreachable + +"87": ; preds = %"23" + unreachable + +"95": ; preds = %"23" + unreachable + +"103": ; preds = %"23" + unreachable + +"104": ; preds = %"23" + unreachable + +"108": ; preds = %"23" + unreachable + +"119": ; preds = %"23" + unreachable + +"130": ; preds = %"23" + unreachable + +"138": ; preds = %"23" + unreachable + +"146": ; preds = %"23" + unreachable + +"162": ; preds = %"23" + unreachable + +"163": ; preds = %"23" + unreachable + +"164": ; preds = %"23" + unreachable + +"166": ; preds = %"23" + unreachable + +"167": ; preds = %"23" + unreachable + +"173": ; preds = %"23", %"23", %"23", %"23", %"23" + unreachable + +"192": ; preds = %"23" + unreachable + +"193": ; preds = %"23" + unreachable + +"194": ; preds = %"23" + unreachable + +"196": ; preds = %"23" + unreachable + +"206": ; preds = %"23" + unreachable + +"231": ; preds = %"23" + unreachable + +"241": ; preds = %"23" + unreachable + +"251": ; preds = %"23" + unreachable + +"261": ; preds = %"23" + unreachable + +"307": ; preds = %"23" + unreachable + +"353": ; preds = %"23" + unreachable + +"354": ; preds = %"23" + unreachable + +"355": ; preds = %"23" + unreachable + +"361": ; preds = %"23" + unreachable + +"367": ; preds = %"23" + unreachable + +"400": ; preds = %"23" + unreachable + +"433": ; preds = %"23" + unreachable + +"466": ; preds = %"23" + unreachable + +"499": ; preds = %"23" + unreachable + +"509": ; preds = %"23" + unreachable + +"519": ; preds = %"23" + unreachable + +"529": ; preds = %"23" + unreachable + +"571": ; preds = %"23" + unreachable + +"589": ; preds = %"23" + unreachable + +"607": ; preds = %"23" + unreachable + +"635": ; preds = %"23" + unreachable + +"655": ; preds = %"23" + unreachable + +"664": ; preds = %"23" + unreachable + +"671": ; preds = %"23" + unreachable + +"680": ; preds = %"23" + unreachable + +"687": ; preds = %"23" + unreachable + +"692": ; preds = %"23" + br label %"1862" + +"698": ; preds = %"23" + unreachable + +"704": ; preds = %"23" + unreachable + +"715": ; preds = %"23", %"23" + unreachable + +"716": ; preds = %"23" + unreachable + +"724": ; preds = %"23", %"23", %"23", %"23" + unreachable + +"725": ; preds = %"23", %"23", %"23", %"23" + unreachable + +"737": ; preds = %"23", %"23", %"23", %"23" + unreachable + +"758": ; preds = %"23" + unreachable + +"759": ; preds = %"23" + unreachable + +"760": ; preds = %"23" + unreachable + +"761": ; preds = %"23" + unreachable + +"763": ; preds = %"23" + unreachable + +"764": ; preds = %"23" + unreachable + +"765": ; preds = %"23" + br label %"766" + +"766": ; preds = %"765", %"23" + unreachable + +"768": ; preds = %"23" + unreachable + +"769": ; preds = %"23" + unreachable + +"770": ; preds = %"23" + unreachable + +"771": ; preds = %"23" + unreachable + +"777": ; preds = %"23" + unreachable + +"778": ; preds = %"23" + unreachable + +"779": ; preds = %"23" + unreachable + +"780": ; preds = %"23" + unreachable + +"821": ; preds = %"23" + unreachable + +"826": ; preds = %"23" + unreachable + +"831": ; preds = %"23" + unreachable + +"832": ; preds = %"23" + unreachable + +"833": ; preds = %"23" + unreachable + +"836": ; preds = %"23", %"23" + unreachable + +"886": ; preds = %"23" + unreachable + +"905": ; preds = %"23" + unreachable + +"978": ; preds = %"23", %"23" + unreachable + +"1136": ; preds = %"23" + unreachable + +"1166": ; preds = %"23" + unreachable + +"1179": ; preds = %"23" + unreachable + +"1201": ; preds = %"23" + unreachable + +"1212": ; preds = %"23", %"23" + unreachable + +"1274": ; preds = %"23" + unreachable + +"1284": ; preds = %"23", %"23" + unreachable + +"1346": ; preds = %"23" + unreachable + +"1347": ; preds = %"23" + unreachable + +"1348": ; preds = %"23" + unreachable + +"1349": ; preds = %"23" + unreachable + +"1350": ; preds = %"23" + unreachable + +"1353": ; preds = %"23", %"23", %"23" + unreachable + +"1355": ; preds = %"23", %"23" + unreachable + +"1357": ; preds = %"23", %"23" + unreachable + +"1358": ; preds = %"23" + unreachable + +"1359": ; preds = %"23" + unreachable + +"1374": ; preds = %"23" + unreachable + +"1375": ; preds = %"23" + %1 = zext i8 undef to i32 ; [#uses=1] + br label %"23" + +"1376": ; preds = %"23" + unreachable + +"1377": ; preds = %"23" + unreachable + +"1378": ; preds = %"23" + unreachable + +"1379": ; preds = %"23" + unreachable + +"1386": ; preds = %"23" + unreachable + +"1394": ; preds = %"23" + unreachable + +"1395": ; preds = %"23" + unreachable + +"1425": ; preds = %"23" + unreachable + +"1426": ; preds = %"23" + unreachable + +"1440": ; preds = %"23" + unreachable + +"1449": ; preds = %"23" + unreachable + +"1455": ; preds = %"23" + unreachable + +"1461": ; preds = %"23" + unreachable + +"1471": ; preds = %"23" + unreachable + +"1482": ; preds = %"23" + unreachable + +"1484": ; preds = %"23" + unreachable + +"1486": ; preds = %"23" + unreachable + +"1489": ; preds = %"23", %"23" + unreachable + +"1492": ; preds = %"23" + unreachable + +"1494": ; preds = %"23", %"23" + unreachable + +"1497": ; preds = %"23" + unreachable + +"1499": ; preds = %"23", %"23" + unreachable + +"1515": ; preds = %"23" + unreachable + +"1546": ; preds = %"23", %"23" + unreachable + +"1566": ; preds = %"23" + br i1 undef, label %"1569", label %"1568" + +"1568": ; preds = %"1566" + unreachable + +"1569": ; preds = %"1566" + unreachable + +"1584": ; preds = %"23" + unreachable + +"1587": ; preds = %"23" + unreachable + +"1591": ; preds = %"23" + unreachable + +"1605": ; preds = %"23" + unreachable + +"1609": ; preds = %"23", %"23" + unreachable + +"1640": ; preds = %"23" + unreachable + +"1648": ; preds = %"23" + unreachable + +"1651": ; preds = %"23" + unreachable + +"1703": ; preds = %"23" + unreachable + +"1710": ; preds = %"23" + unreachable + +"1718": ; preds = %"23" + unreachable + +"1724": ; preds = %"23" + unreachable + +"1725": ; preds = %"23" + unreachable + +"1726": ; preds = %"23" + unreachable + +"1727": ; preds = %"23" + unreachable + +"1728": ; preds = %"23" + unreachable + +"1731": ; preds = %"23" + unreachable + +"1732": ; preds = %"23" + unreachable + +"1733": ; preds = %"23" + unreachable + +"1734": ; preds = %"23" + unreachable + +"1735": ; preds = %"23" + unreachable + +"1741": ; preds = %"23" + unreachable + +"1750": ; preds = %"23" + unreachable + +"1752": ; preds = %"23" + unreachable + +"1754": ; preds = %"23" + unreachable + +"1755": ; preds = %"23" + unreachable + +"1757": ; preds = %"23" + unreachable + +"1759": ; preds = %"23" + unreachable + +"1761": ; preds = %"23" + unreachable + +"1764": ; preds = %"23", %"23" + %2 = icmp eq i32 %0, 168 ; [#uses=0] + unreachable + +"1766": ; preds = %"23" + unreachable + +"1768": ; preds = %"23" + unreachable + +"1775": ; preds = %"23", %"23" + unreachable + +"1781": ; preds = %"23", %"23" + unreachable + +"1790": ; preds = %"23" + unreachable + +"1791": ; preds = %"23" + unreachable + +"1801": ; preds = %"23" + unreachable + +"1802": ; preds = %"23" + unreachable + +"1803": ; preds = %"23" + unreachable + +"1805": ; preds = %"23" + unreachable + +"1807": ; preds = %"23" + unreachable + +"1809": ; preds = %"23" + unreachable + +"1817": ; preds = %"23" + unreachable + +"1819": ; preds = %"23" + unreachable + +"1821": ; preds = %"23" + unreachable + +"1823": ; preds = %"23" + unreachable + +"1825": ; preds = %"23" + unreachable + +"1827": ; preds = %"23" + unreachable + +"1836": ; preds = %"23", %"23" + br label %"1862" + +"1845": ; preds = %"23", %"23" + unreachable + +"1848": ; preds = %"23" + unreachable + +"1849": ; preds = %"23" + unreachable + +"1851": ; preds = %"23" + unreachable + +"1853": ; preds = %"23" + unreachable + +"1856": ; preds = %"23" + unreachable + +"1861": ; preds = %"23", %"23" + unreachable + +"41": ; preds = %"23", %"23" + unreachable + +"1862": ; preds = %"1836", %"692" + unreachable +} From vhernandez at apple.com Mon Nov 9 12:29:14 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Mon, 9 Nov 2009 10:29:14 -0800 Subject: [llvm-commits] [llvm] r86525 - /llvm/trunk/lib/VMCore/Instructions.cpp In-Reply-To: <200911090712.nA97C1pV013033@zion.cs.uiuc.edu> References: <200911090712.nA97C1pV013033@zion.cs.uiuc.edu> Message-ID: <713246E4-FA50-4B27-AE69-2113326DF266@apple.com> Thanks for pointing this out, Duncan, and for fixing this, Chris. Victor On Nov 8, 2009, at 11:12 PM, Chris Lattner wrote: > Author: lattner > Date: Mon Nov 9 01:12:01 2009 > New Revision: 86525 > > URL: http://llvm.org/viewvc/llvm-project?rev=86525&view=rev > Log: > make this handle redefinition of malloc with different prototype > correctly. > > Modified: > llvm/trunk/lib/VMCore/Instructions.cpp > > Modified: llvm/trunk/lib/VMCore/Instructions.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=86525&r1=86524&r2=86525&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/VMCore/Instructions.cpp (original) > +++ llvm/trunk/lib/VMCore/Instructions.cpp Mon Nov 9 01:12:01 2009 > @@ -568,8 +568,7 @@ > const Type *VoidTy = Type::getVoidTy(M->getContext()); > const Type *IntPtrTy = Type::getInt8PtrTy(M->getContext()); > // prototype free as "void free(void*)" > - Function *FreeFunc = cast(M->getOrInsertFunction > ("free", VoidTy, > - > IntPtrTy, NULL)); > + Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, > IntPtrTy, NULL); > CallInst* Result = NULL; > Value *PtrCast = Source; > if (InsertBefore) { > @@ -582,7 +581,8 @@ > Result = CallInst::Create(FreeFunc, PtrCast, ""); > } > Result->setTailCall(); > - Result->setCallingConv(FreeFunc->getCallingConv()); > + if (Function *F = dyn_cast(FreeFunc)) > + Result->setCallingConv(F->getCallingConv()); > > return Result; > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gohman at apple.com Mon Nov 9 12:40:39 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 09 Nov 2009 18:40:39 -0000 Subject: [llvm-commits] [llvm] r86572 - /llvm/trunk/docs/LangRef.html Message-ID: <200911091840.nA9IedCK024858@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 12:40:39 2009 New Revision: 86572 URL: http://llvm.org/viewvc/llvm-project?rev=86572&view=rev Log: Remove the "special case" for zero-length arrays, and rephrase this paragraph to be more precise. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=86572&r1=86571&r2=86572&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Mon Nov 9 12:40:39 2009 @@ -1576,12 +1576,13 @@ -

Note that 'variable sized arrays' can be implemented in LLVM with a zero - length array. Normally, accesses past the end of an array are undefined in - LLVM (e.g. it is illegal to access the 5th element of a 3 element array). As - a special case, however, zero length arrays are recognized to be variable - length. This allows implementation of 'pascal style arrays' with the LLVM - type "{ i32, [0 x float]}", for example.

+

Except when the inbounds keyword is present, there is no limitation + on indexing beyond the end of the array implied by the static type (though + any loads or stores must of course be within the bounds of the allocated + object!). This means that single-dimension 'variable sized array' addressing + can be implemented in LLVM with a zero length array type. An implementation + of 'pascal style arrays' in LLVM could use the type + "{ i32, [0 x float]}", for example.

Note that the code generator does not yet support large aggregate types to be used as function return types. The specific limit on how large an aggregate From baldrick at free.fr Mon Nov 9 12:49:54 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 09 Nov 2009 19:49:54 +0100 Subject: [llvm-commits] [llvm] r86569 - in /llvm/trunk: lib/Transforms/Utils/LCSSA.cpp test/Transforms/LCSSA/indirectbr.ll In-Reply-To: <200911091828.nA9ISOw3024412@zion.cs.uiuc.edu> References: <200911091828.nA9ISOw3024412@zion.cs.uiuc.edu> Message-ID: <4AF86452.6080100@free.fr> Hi Dan, thanks for fixing this. > + // If the exit block has a predecessor not within the loop, arrange for > + // the incomging value use corresponding to that predecessor to be incomging -> incoming Ciao, Duncan. From baldrick at free.fr Mon Nov 9 12:52:12 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 09 Nov 2009 19:52:12 +0100 Subject: [llvm-commits] [llvm] r86572 - /llvm/trunk/docs/LangRef.html In-Reply-To: <200911091840.nA9IedCK024858@zion.cs.uiuc.edu> References: <200911091840.nA9IedCK024858@zion.cs.uiuc.edu> Message-ID: <4AF864DC.1050701@free.fr> Hi Dan, > +

Except when the inbounds keyword is present, there is no limitation > + on indexing beyond the end of the array implied by the static type (though > + any loads or stores must of course be within the bounds of the allocated > + object!). This means that single-dimension 'variable sized array' addressing > + can be implemented in LLVM with a zero length array type. An implementation > + of 'pascal style arrays' in LLVM could use the type > + "{ i32, [0 x float]}", for example.

does this mean that "inbounds" means that you are not allowed to index off the end of the *type*, even if you are not indexing off the end of the allocated object? Ciao, Duncan. From gohman at apple.com Mon Nov 9 12:59:22 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 09 Nov 2009 18:59:22 -0000 Subject: [llvm-commits] [llvm] r86575 - /llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Message-ID: <200911091859.nA9IxMhv025519@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 12:59:22 2009 New Revision: 86575 URL: http://llvm.org/viewvc/llvm-project?rev=86575&view=rev Log: Fix a comment in a typo that Duncan noticed. Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LCSSA.cpp?rev=86575&r1=86574&r2=86575&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LCSSA.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Mon Nov 9 12:59:22 2009 @@ -235,7 +235,7 @@ PN->addIncoming(Inst, *PI); // If the exit block has a predecessor not within the loop, arrange for - // the incomging value use corresponding to that predecessor to be + // the incoming value use corresponding to that predecessor to be // rewritten in terms of a different LCSSA PHI. if (!inLoop(*PI)) UsesToRewrite.push_back( From gohman at apple.com Mon Nov 9 13:01:53 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 09 Nov 2009 19:01:53 -0000 Subject: [llvm-commits] [llvm] r86576 - /llvm/trunk/docs/LangRef.html Message-ID: <200911091901.nA9J1rL2025650@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 13:01:53 2009 New Revision: 86576 URL: http://llvm.org/viewvc/llvm-project?rev=86576&view=rev Log: The inbounds keyword isn't relevant to overindexing of static array types. Thanks to Duncan for pointing this out! Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=86576&r1=86575&r2=86576&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Mon Nov 9 13:01:53 2009 @@ -1576,13 +1576,12 @@ -

Except when the inbounds keyword is present, there is no limitation - on indexing beyond the end of the array implied by the static type (though - any loads or stores must of course be within the bounds of the allocated - object!). This means that single-dimension 'variable sized array' addressing - can be implemented in LLVM with a zero length array type. An implementation - of 'pascal style arrays' in LLVM could use the type - "{ i32, [0 x float]}", for example.

+

There is no restriction on indexing beyond the end of the array implied by + a static type (though there are restrictions on indexing beyond the bounds + of an allocated object in some cases). This means that single-dimension + 'variable sized array' addressing can be implemented in LLVM with a zero + length array type. An implementation of 'pascal style arrays' in LLVM could + use the type "{ i32, [0 x float]}", for example.

Note that the code generator does not yet support large aggregate types to be used as function return types. The specific limit on how large an aggregate From gohman at apple.com Mon Nov 9 13:03:12 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 9 Nov 2009 11:03:12 -0800 Subject: [llvm-commits] [llvm] r86572 - /llvm/trunk/docs/LangRef.html In-Reply-To: <4AF864DC.1050701@free.fr> References: <200911091840.nA9IedCK024858@zion.cs.uiuc.edu> <4AF864DC.1050701@free.fr> Message-ID: <9C55CAD3-EEF8-4F8F-A191-E1E14C99BAEC@apple.com> On Nov 9, 2009, at 10:52 AM, Duncan Sands wrote: > Hi Dan, > >> +

Except when the inbounds keyword is present, there is no limitation >> + on indexing beyond the end of the array implied by the static type (though >> + any loads or stores must of course be within the bounds of the allocated >> + object!). This means that single-dimension 'variable sized array' addressing >> + can be implemented in LLVM with a zero length array type. An implementation >> + of 'pascal style arrays' in LLVM could use the type >> + "{ i32, [0 x float]}", for example.

> > does this mean that "inbounds" means that you are not allowed to index off the > end of the *type*, even if you are not indexing off the end of the allocated > object? No; it means I made a mistake. Thanks! Dan From david_goodwin at apple.com Mon Nov 9 13:22:18 2009 From: david_goodwin at apple.com (David Goodwin) Date: Mon, 09 Nov 2009 19:22:18 -0000 Subject: [llvm-commits] [llvm] r86580 - /llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Message-ID: <200911091922.nA9JMIKi026401@zion.cs.uiuc.edu> Author: david_goodwin Date: Mon Nov 9 13:22:17 2009 New Revision: 86580 URL: http://llvm.org/viewvc/llvm-project?rev=86580&view=rev Log: Fix dependencies added to model memory aliasing for post-RA scheduling. The dependencies were overly conservative for memory access that are known not to alias. Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=86580&r1=86579&r2=86580&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Mon Nov 9 13:22:17 2009 @@ -112,12 +112,13 @@ V = getUnderlyingObject(V); if (const PseudoSourceValue *PSV = dyn_cast(V)) { - MayAlias = PSV->mayAlias(MFI); // For now, ignore PseudoSourceValues which may alias LLVM IR values // because the code that uses this function has no way to cope with // such aliases. if (PSV->isAliased(MFI)) return 0; + + MayAlias = PSV->mayAlias(MFI); return V; } @@ -127,23 +128,6 @@ return 0; } -static bool mayUnderlyingObjectForInstrAlias(const MachineInstr *MI, - const MachineFrameInfo *MFI) { - if (!MI->hasOneMemOperand() || - !(*MI->memoperands_begin())->getValue() || - (*MI->memoperands_begin())->isVolatile()) - return true; - - const Value *V = (*MI->memoperands_begin())->getValue(); - if (!V) - return true; - - V = getUnderlyingObject(V); - if (const PseudoSourceValue *PSV = dyn_cast(V)) - return PSV->mayAlias(MFI); - return true; -} - void ScheduleDAGInstrs::StartBlock(MachineBasicBlock *BB) { if (MachineLoop *ML = MLI.getLoopFor(BB)) if (BB == ML->getLoopLatch()) { @@ -163,16 +147,15 @@ // We build scheduling units by walking a block's instruction list from bottom // to top. - // Remember where a generic side-effecting instruction is as we procede. If - // ChainMMO is null, this is assumed to have arbitrary side-effects. If - // ChainMMO is non-null, then Chain makes only a single memory reference. - SUnit *Chain = 0; - MachineMemOperand *ChainMMO = 0; - - // Memory references to specific known memory locations are tracked so that - // they can be given more precise dependencies. - std::map MemDefs; - std::map > MemUses; + // Remember where a generic side-effecting instruction is as we procede. + SUnit *BarrierChain = 0, *AliasChain = 0; + + // Memory references to specific known memory locations are tracked + // so that they can be given more precise dependencies. We track + // separately the known memory locations that may alias and those + // that are known not to alias + std::map AliasMemDefs, NonAliasMemDefs; + std::map > AliasMemUses, NonAliasMemUses; // Check to see if the scheduler cares about latencies. bool UnitLatencies = ForceUnitLatencies(); @@ -347,114 +330,132 @@ // produce more precise dependence information. #define STORE_LOAD_LATENCY 1 unsigned TrueMemOrderLatency = 0; - if (TID.isCall() || TID.hasUnmodeledSideEffects()) { - new_chain: - // This is the conservative case. Add dependencies on all memory - // references. - if (Chain) - Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); - Chain = SU; + if (TID.isCall() || TID.hasUnmodeledSideEffects() || + (MI->hasVolatileMemoryRef() && + (!TID.mayLoad() || !MI->isInvariantLoad(AA)))) { + // Be conservative with these and add dependencies on all memory + // references, even those that are known to not alias. + for (std::map::iterator I = + NonAliasMemDefs.begin(), E = NonAliasMemDefs.end(); I != E; ++I) { + I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + } + for (std::map >::iterator I = + NonAliasMemUses.begin(), E = NonAliasMemUses.end(); I != E; ++I) { + for (unsigned i = 0, e = I->second.size(); i != e; ++i) + I->second[i]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency)); + } + NonAliasMemDefs.clear(); + NonAliasMemUses.clear(); + // Add SU to the barrier chain. + if (BarrierChain) + BarrierChain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + BarrierChain = SU; + + // fall-through + new_alias_chain: + // Chain all possibly aliasing memory references though SU. + if (AliasChain) + AliasChain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + AliasChain = SU; for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) PendingLoads[k]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency)); - PendingLoads.clear(); - for (std::map::iterator I = MemDefs.begin(), - E = MemDefs.end(); I != E; ++I) { + for (std::map::iterator I = AliasMemDefs.begin(), + E = AliasMemDefs.end(); I != E; ++I) { I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); - I->second = SU; } for (std::map >::iterator I = - MemUses.begin(), E = MemUses.end(); I != E; ++I) { + AliasMemUses.begin(), E = AliasMemUses.end(); I != E; ++I) { for (unsigned i = 0, e = I->second.size(); i != e; ++i) I->second[i]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency)); - I->second.clear(); - I->second.push_back(SU); } - // See if it is known to just have a single memory reference. - MachineInstr *ChainMI = Chain->getInstr(); - const TargetInstrDesc &ChainTID = ChainMI->getDesc(); - if (!ChainTID.isCall() && - !ChainTID.hasUnmodeledSideEffects() && - ChainMI->hasOneMemOperand() && - !(*ChainMI->memoperands_begin())->isVolatile() && - (*ChainMI->memoperands_begin())->getValue()) - // We know that the Chain accesses one specific memory location. - ChainMMO = *ChainMI->memoperands_begin(); - else - // Unknown memory accesses. Assume the worst. - ChainMMO = 0; + PendingLoads.clear(); + AliasMemDefs.clear(); + AliasMemUses.clear(); } else if (TID.mayStore()) { bool MayAlias = true; TrueMemOrderLatency = STORE_LOAD_LATENCY; if (const Value *V = getUnderlyingObjectForInstr(MI, MFI, MayAlias)) { // A store to a specific PseudoSourceValue. Add precise dependencies. - // Handle the def in MemDefs, if there is one. - std::map::iterator I = MemDefs.find(V); - if (I != MemDefs.end()) { + // Record the def in MemDefs, first adding a dep if there is + // an existing def. + std::map::iterator I = + ((MayAlias) ? AliasMemDefs.find(V) : NonAliasMemDefs.find(V)); + std::map::iterator IE = + ((MayAlias) ? AliasMemDefs.end() : NonAliasMemDefs.end()); + if (I != IE) { I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0, /*Reg=*/0, /*isNormalMemory=*/true)); I->second = SU; } else { - MemDefs[V] = SU; + if (MayAlias) + AliasMemDefs[V] = SU; + else + NonAliasMemDefs[V] = SU; } // Handle the uses in MemUses, if there are any. std::map >::iterator J = - MemUses.find(V); - if (J != MemUses.end()) { + ((MayAlias) ? AliasMemUses.find(V) : NonAliasMemUses.find(V)); + std::map >::iterator JE = + ((MayAlias) ? AliasMemUses.end() : NonAliasMemUses.end()); + if (J != JE) { for (unsigned i = 0, e = J->second.size(); i != e; ++i) J->second[i]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency, /*Reg=*/0, /*isNormalMemory=*/true)); J->second.clear(); } if (MayAlias) { - // Add dependencies from all the PendingLoads, since without - // memoperands we must assume they alias anything. + // Add dependencies from all the PendingLoads, i.e. loads + // with no underlying object. for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) PendingLoads[k]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency)); - // Add a general dependence too, if needed. - if (Chain) - Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + // Add dependence on alias chain, if needed. + if (AliasChain) + AliasChain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); } + // Add dependence on barrier chain, if needed. + if (BarrierChain) + BarrierChain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); } else { // Treat all other stores conservatively. - goto new_chain; + goto new_alias_chain; } } else if (TID.mayLoad()) { bool MayAlias = true; TrueMemOrderLatency = 0; if (MI->isInvariantLoad(AA)) { // Invariant load, no chain dependencies needed! - } else if (const Value *V = - getUnderlyingObjectForInstr(MI, MFI, MayAlias)) { - // A load from a specific PseudoSourceValue. Add precise dependencies. - std::map::iterator I = MemDefs.find(V); - if (I != MemDefs.end()) - I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0, /*Reg=*/0, - /*isNormalMemory=*/true)); - MemUses[V].push_back(SU); - - // Add a general dependence too, if needed. - if (Chain && (!ChainMMO || - (ChainMMO->isStore() || ChainMMO->isVolatile()))) - Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); - } else if (MI->hasVolatileMemoryRef()) { - // Treat volatile loads conservatively. Note that this includes - // cases where memoperand information is unavailable. - goto new_chain; } else { - // A "MayAlias" load. Depend on the general chain, as well as on - // all stores. In the absense of MachineMemOperand information, - // we can't even assume that the load doesn't alias well-behaved - // memory locations. - if (Chain) - Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); - for (std::map::iterator I = MemDefs.begin(), - E = MemDefs.end(); I != E; ++I) { - SUnit *DefSU = I->second; - if (mayUnderlyingObjectForInstrAlias(DefSU->getInstr(), MFI)) - DefSU->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + if (const Value *V = + getUnderlyingObjectForInstr(MI, MFI, MayAlias)) { + // A load from a specific PseudoSourceValue. Add precise dependencies. + std::map::iterator I = + ((MayAlias) ? AliasMemDefs.find(V) : NonAliasMemDefs.find(V)); + std::map::iterator IE = + ((MayAlias) ? AliasMemDefs.end() : NonAliasMemDefs.end()); + if (I != IE) + I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0, /*Reg=*/0, + /*isNormalMemory=*/true)); + if (MayAlias) + AliasMemUses[V].push_back(SU); + else + NonAliasMemUses[V].push_back(SU); + } else { + // A load with no underlying object. Depend on all + // potentially aliasing stores. + for (std::map::iterator I = + AliasMemDefs.begin(), E = AliasMemDefs.end(); I != E; ++I) + I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + + PendingLoads.push_back(SU); + MayAlias = true; } - PendingLoads.push_back(SU); - } + + // Add dependencies on alias and barrier chains, if needed. + if (MayAlias && AliasChain) + AliasChain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + if (BarrierChain) + BarrierChain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + } } } From gohman at apple.com Mon Nov 9 13:29:11 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 09 Nov 2009 19:29:11 -0000 Subject: [llvm-commits] [llvm] r86582 - in /llvm/trunk: lib/Analysis/BasicAliasAnalysis.cpp test/Transforms/GVN/null-aliases-nothing.ll Message-ID: <200911091929.nA9JTBHY026715@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 13:29:11 2009 New Revision: 86582 URL: http://llvm.org/viewvc/llvm-project?rev=86582&view=rev Log: Default-addressspace null pointers don't alias anything. This allows GVN to be more aggressive. Patch by Hans Wennborg! (with a comment added by me) Added: llvm/trunk/test/Transforms/GVN/null-aliases-nothing.ll Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=86582&r1=86581&r2=86582&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Mon Nov 9 13:29:11 2009 @@ -646,6 +646,15 @@ const Value *O1 = V1->getUnderlyingObject(); const Value *O2 = V2->getUnderlyingObject(); + // Null values in the default address space don't point to any object, so they + // don't alias any other pointer. + if (const ConstantPointerNull *CPN = dyn_cast(O1)) + if (CPN->getType()->getAddressSpace() == 0) + return NoAlias; + if (const ConstantPointerNull *CPN = dyn_cast(O2)) + if (CPN->getType()->getAddressSpace() == 0) + return NoAlias; + if (O1 != O2) { // If V1/V2 point to two different objects we know that we have no alias. if (isIdentifiedObject(O1) && isIdentifiedObject(O2)) Added: llvm/trunk/test/Transforms/GVN/null-aliases-nothing.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/null-aliases-nothing.ll?rev=86582&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GVN/null-aliases-nothing.ll (added) +++ llvm/trunk/test/Transforms/GVN/null-aliases-nothing.ll Mon Nov 9 13:29:11 2009 @@ -0,0 +1,20 @@ +; RUN: opt %s -gvn -S | FileCheck %s + +%t = type { i32 } +declare void @test1f(i8*) + +define void @test1(%t* noalias %stuff ) { + %p = getelementptr inbounds %t* %stuff, i32 0, i32 0 + %before = load i32* %p + + call void @test1f(i8* null) + + %after = load i32* %p ; <--- This should be a dead load + %sum = add i32 %before, %after; + + store i32 %sum, i32* %p + ret void +; CHECK: load +; CHECK-NOT: load +; CHECK: ret void +} From clattner at apple.com Mon Nov 9 13:35:23 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 9 Nov 2009 11:35:23 -0800 Subject: [llvm-commits] [llvm] r86569 - in /llvm/trunk: lib/Transforms/Utils/LCSSA.cpp test/Transforms/LCSSA/indirectbr.ll In-Reply-To: <200911091828.nA9ISOw3024412@zion.cs.uiuc.edu> References: <200911091828.nA9ISOw3024412@zion.cs.uiuc.edu> Message-ID: <7D50C282-1343-4BAA-BF50-5CDF6207E6AD@apple.com> On Nov 9, 2009, at 10:28 AM, Dan Gohman wrote: > Author: djg > Date: Mon Nov 9 12:28:24 2009 > New Revision: 86569 > > URL: http://llvm.org/viewvc/llvm-project?rev=86569&view=rev > Log: > Generalize LCSSA to handle loops with exits with predecessors outside > the loop. This is needed because with indirectbr it may not be > possible > for LoopSimplify to guarantee that all loop exit predecessors are > inside the loop. This fixes PR5437. > > LCCSA no longer actually requires LoopSimplify form, but for now it > must still have the dependency because the PassManager doesn't know > how to schedule LoopSimplify otherwise. Dan, can you please manually shrink the testcase? -Chris From gohman at apple.com Mon Nov 9 13:38:46 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 09 Nov 2009 19:38:46 -0000 Subject: [llvm-commits] [llvm] r86583 - in /llvm/trunk: include/llvm/CodeGen/MachineRegisterInfo.h lib/CodeGen/MachineInstr.cpp Message-ID: <200911091938.nA9Jck7i027097@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 13:38:45 2009 New Revision: 86583 URL: http://llvm.org/viewvc/llvm-project?rev=86583&view=rev Log: Print "..." instead of all the uninteresting register clobbers on call instructions. This makes CodeGen dumps significantly less noisy. Example before: BL , %R0, %R1, %R2, %R3, %R12, %LR, %D0, %D1, %D2, %D3, %D4, %D5, %D6, %D7, %D16, %D17, %D18, %D19, %D20, %D21, %D22, %D23, %D24, %D25, %D26, %D27, %D28, %D29, %D30, %D31, %CPSR, %FPSCR Same example after: BL , %R0, %R1, %LR, %CPSR, ... Modified: llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h llvm/trunk/lib/CodeGen/MachineInstr.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h?rev=86583&r1=86582&r2=86583&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h Mon Nov 9 13:38:45 2009 @@ -243,6 +243,12 @@ return true; return false; } + bool isLiveOut(unsigned Reg) const { + for (liveout_iterator I = liveout_begin(), E = liveout_end(); I != E; ++I) + if (*I == Reg) + return true; + return false; + } private: void HandleVRegListReallocation(); Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=86583&r1=86582&r2=86583&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Mon Nov 9 13:38:45 2009 @@ -189,19 +189,19 @@ /// print - Print the specified machine operand. /// void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { + // If the instruction is embedded into a basic block, we can find the + // target info for the instruction. + if (!TM) + if (const MachineInstr *MI = getParent()) + if (const MachineBasicBlock *MBB = MI->getParent()) + if (const MachineFunction *MF = MBB->getParent()) + TM = &MF->getTarget(); + switch (getType()) { case MachineOperand::MO_Register: if (getReg() == 0 || TargetRegisterInfo::isVirtualRegister(getReg())) { OS << "%reg" << getReg(); } else { - // If the instruction is embedded into a basic block, we can find the - // target info for the instruction. - if (TM == 0) - if (const MachineInstr *MI = getParent()) - if (const MachineBasicBlock *MBB = MI->getParent()) - if (const MachineFunction *MF = MBB->getParent()) - TM = &MF->getTarget(); - if (TM) OS << "%" << TM->getRegisterInfo()->get(getReg()).Name; else @@ -1061,9 +1061,16 @@ } void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { - unsigned StartOp = 0, e = getNumOperands(); + // We can be a bit tidier if we know the TargetMachine and/or MachineFunction. + const MachineFunction *MF = 0; + if (const MachineBasicBlock *MBB = getParent()) { + MF = MBB->getParent(); + if (!TM && MF) + TM = &MF->getTarget(); + } // Print explicitly defined operands on the left of an assignment syntax. + unsigned StartOp = 0, e = getNumOperands(); for (; StartOp < e && getOperand(StartOp).isReg() && getOperand(StartOp).isDef() && !getOperand(StartOp).isImplicit(); @@ -1079,11 +1086,45 @@ OS << getDesc().getName(); // Print the rest of the operands. + bool OmittedAnyCallClobbers = false; + bool FirstOp = true; for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { - if (i != StartOp) - OS << ","; + const MachineOperand &MO = getOperand(i); + + // Omit call-clobbered registers which aren't used anywhere. This makes + // call instructions much less noisy on targets where calls clobber lots + // of registers. Don't rely on MO.isDead() because we may be called before + // LiveVariables is run, or we may be looking at a non-allocatable reg. + if (MF && getDesc().isCall() && + MO.isReg() && MO.isImplicit() && MO.isDef()) { + unsigned Reg = MO.getReg(); + if (Reg != 0 && TargetRegisterInfo::isPhysicalRegister(Reg)) { + const MachineRegisterInfo &MRI = MF->getRegInfo(); + if (MRI.use_empty(Reg) && !MRI.isLiveOut(Reg)) { + bool HasAliasLive = false; + for (const unsigned *Alias = TM->getRegisterInfo()->getAliasSet(Reg); + unsigned AliasReg = *Alias; ++Alias) + if (!MRI.use_empty(AliasReg) || MRI.isLiveOut(AliasReg)) { + HasAliasLive = true; + break; + } + if (!HasAliasLive) { + OmittedAnyCallClobbers = true; + continue; + } + } + } + } + + if (FirstOp) FirstOp = false; else OS << ","; OS << " "; - getOperand(i).print(OS, TM); + MO.print(OS, TM); + } + + // Briefly indicate whether any call clobbers were omitted. + if (OmittedAnyCallClobbers) { + if (FirstOp) FirstOp = false; else OS << ","; + OS << " ..."; } bool HaveSemi = false; @@ -1099,12 +1140,11 @@ } } - if (!debugLoc.isUnknown()) { + if (!debugLoc.isUnknown() && MF) { if (!HaveSemi) OS << ";"; HaveSemi = true; // TODO: print InlinedAtLoc information - const MachineFunction *MF = getParent()->getParent(); DebugLocTuple DLT = MF->getDebugLocTuple(debugLoc); DICompileUnit CU(DLT.Scope); if (!CU.isNull()) From deeppatel1987 at gmail.com Mon Nov 9 14:42:29 2009 From: deeppatel1987 at gmail.com (Sandeep Patel) Date: Mon, 9 Nov 2009 20:42:29 +0000 Subject: [llvm-commits] sret-demotion for large struct returns working on x86! In-Reply-To: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> References: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> Message-ID: <305d6f60911091242p3c122cadqc9baf8c477799696@mail.gmail.com> On Mon, Nov 9, 2009 at 2:37 AM, Kenneth Uildriks wrote: > If a struct can't be returned in registers, have SelectionDAGBuild > insert a hidden sret parameter and have return instructions store the > return value through the hidden pointer. ?Formal arguments, return > instructions, and calls are all updated as needed. > > Only x86 has the code to actually check whether sret-demotion is > needed.... other platforms invariably report that they can return > values in registers, even when they can't. There is definitely an ABI issue here. For ARM AAPCS-VFP, we need to decide that a aggregate is to be passed in registers based on information like unions which aren't represented in the LLVM IR. Perhaps I've missed the overall goal. If the CC is "fast" then this sort of thing makes a lot of sense, but "C" and other CCs need to be established by the front-end and not perturbed by the backend. deep From kennethuil at gmail.com Mon Nov 9 14:59:09 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Mon, 9 Nov 2009 14:59:09 -0600 Subject: [llvm-commits] sret-demotion for large struct returns working on x86! In-Reply-To: <305d6f60911091242p3c122cadqc9baf8c477799696@mail.gmail.com> References: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> <305d6f60911091242p3c122cadqc9baf8c477799696@mail.gmail.com> Message-ID: <400d33ea0911091259t1b72e66ejd55129973916b57c@mail.gmail.com> On Mon, Nov 9, 2009 at 2:42 PM, Sandeep Patel wrote: > On Mon, Nov 9, 2009 at 2:37 AM, Kenneth Uildriks wrote: >> If a struct can't be returned in registers, have SelectionDAGBuild >> insert a hidden sret parameter and have return instructions store the >> return value through the hidden pointer. ?Formal arguments, return >> instructions, and calls are all updated as needed. >> >> Only x86 has the code to actually check whether sret-demotion is >> needed.... other platforms invariably report that they can return >> values in registers, even when they can't. > > There is definitely an ABI issue here. For ARM AAPCS-VFP, we need to > decide that a aggregate is to be passed in registers based on > information like unions which aren't represented in the LLVM IR. > > Perhaps I've missed the overall goal. If the CC is "fast" then this > sort of thing makes a lot of sense, but "C" and other CCs need to be > established by the front-end and not perturbed by the backend. > > deep > The trouble is that the front-end doesn't have enough information. You need to get all the way to the SelectionDAG before you can even begin to determine whether the target/calling convention combo is capable of returning your struct in registers... and if it isn't, SelectionDAG falls over and dies when it hits the function. So you can't guarantee while building your IR that SelectionDAG won't abort (unless you hardcode target-specific rules into your front-end). This transformation will only kick in in cases where the present version falls over and dies. Existing, working code will behave no differently. Existing target-specific front-ends will not be affected. From gohman at apple.com Mon Nov 9 15:14:46 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 9 Nov 2009 13:14:46 -0800 Subject: [llvm-commits] sret-demotion for large struct returns working on x86! In-Reply-To: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> References: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> Message-ID: <5CC43A6B-57E4-42A7-B1E6-CCD9875F65D7@apple.com> On Nov 8, 2009, at 6:37 PM, Kenneth Uildriks wrote: > If a struct can't be returned in registers, have SelectionDAGBuild > insert a hidden sret parameter and have return instructions store the > return value through the hidden pointer. Formal arguments, return > instructions, and calls are all updated as needed. > > Only x86 has the code to actually check whether sret-demotion is > needed.... other platforms invariably report that they can return > values in registers, even when they can't. Hello, Overall this patch looks good. Thanks for working on this! I have a few comments. > + // True if the function needs to be sret-demoted > + bool CantLowerReturn; > > + // Virtual register to hold the sret pointer for sret-demotion > + unsigned DemoteRegister; Would it be possible to put this field in FunctionLoweringInfo instead of MachineFunction? It's information that's only really relevant during lowering to the SelectionDAG. > - if (F->paramHasAttr(0, Attribute::SExt)) > - ExtendKind = ISD::SIGN_EXTEND; > - else if (F->paramHasAttr(0, Attribute::ZExt)) > - ExtendKind = ISD::ZERO_EXTEND; I'm unclear on why this code is being removed. Can you explain what's happening here? > + if (!CanLowerReturn) > + { In general, LLVM style has the opening brace on the same line as the if, else, for, etc. Dan From isanbard at gmail.com Mon Nov 9 15:20:14 2009 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 09 Nov 2009 21:20:14 -0000 Subject: [llvm-commits] [llvm] r86588 - /llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Message-ID: <200911092120.nA9LKEul031824@zion.cs.uiuc.edu> Author: void Date: Mon Nov 9 15:20:14 2009 New Revision: 86588 URL: http://llvm.org/viewvc/llvm-project?rev=86588&view=rev Log: The jump table was being generated before the end label for exception handling was generated. This caused code like this: ## The asm code for the function .section __TEXT,__const .align 2 lJTI11_0: LJTI11_0: .long LBB11_16 .long LBB11_4 .long LBB11_5 .long LBB11_6 .long LBB11_7 .long LBB11_8 .long LBB11_9 .long LBB11_10 .long LBB11_11 .long LBB11_12 .long LBB11_13 .long LBB11_14 Leh_func_end11: ## <---now in the wrong section! The `Leh_func_end11' would then end up in the wrong section, causing the resulting EH frame information to be wrong: __ZL11CheckRightsjPKcbRbRP6NSData.eh: .set Lset500eh,Leh_frame_end11-Leh_frame_begin11 .long Lset500eh ; Length of Frame Information Entry Leh_frame_begin11: .long Leh_frame_begin11-Leh_frame_common .long Leh_func_begin11-. .set Lset501eh,Leh_func_end11-Leh_func_begin11 .long Lset501eh ; FDE address range `Lset501eh' is now something huge instead of the real value. The X86 back-end generates the jump table after the EH information is emitted. Do the same here. Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp?rev=86588&r1=86587&r2=86588&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Mon Nov 9 15:20:14 2009 @@ -672,14 +672,14 @@ O << "\t.size\t" << CurrentFnName << ",.-" << CurrentFnName << '\n'; - // Print out jump tables referenced by the function. - EmitJumpTableInfo(MF.getJumpTableInfo(), MF); - OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM)); // Emit post-function debug information. DW->EndFunction(&MF); + // Print out jump tables referenced by the function. + EmitJumpTableInfo(MF.getJumpTableInfo(), MF); + // We didn't modify anything. return false; } From kennethuil at gmail.com Mon Nov 9 15:43:02 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Mon, 9 Nov 2009 15:43:02 -0600 Subject: [llvm-commits] sret-demotion for large struct returns working on x86! In-Reply-To: <5CC43A6B-57E4-42A7-B1E6-CCD9875F65D7@apple.com> References: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> <5CC43A6B-57E4-42A7-B1E6-CCD9875F65D7@apple.com> Message-ID: <400d33ea0911091343w1549702enbbbb0c7b34b75cfa@mail.gmail.com> On Mon, Nov 9, 2009 at 3:14 PM, Dan Gohman wrote: > > On Nov 8, 2009, at 6:37 PM, Kenneth Uildriks wrote: > >> If a struct can't be returned in registers, have SelectionDAGBuild >> insert a hidden sret parameter and have return instructions store the >> return value through the hidden pointer. ?Formal arguments, return >> instructions, and calls are all updated as needed. >> >> Only x86 has the code to actually check whether sret-demotion is >> needed.... other platforms invariably report that they can return >> values in registers, even when they can't. > > Hello, > > Overall this patch looks good. Thanks for working on this! I > have a few comments. > >> + ?// True if the function needs to be sret-demoted >> + ?bool CantLowerReturn; >> >> + ?// Virtual register to hold the sret pointer for sret-demotion >> + ?unsigned DemoteRegister; > > Would it be possible to put this field in FunctionLoweringInfo > instead of MachineFunction? It's information that's only really > relevant during lowering to the SelectionDAG. Thanks for pointing that out... I found code in SelectionDAGBuild that pulls the FunctionLoweringInfo from the DAG. Assuming I always get the same instance back for the same function, it should be pretty easy. > >> - ? ?if (F->paramHasAttr(0, Attribute::SExt)) >> - ? ? ?ExtendKind = ISD::SIGN_EXTEND; >> - ? ?else if (F->paramHasAttr(0, Attribute::ZExt)) >> - ? ? ?ExtendKind = ISD::ZERO_EXTEND; > > I'm unclear on why this code is being removed. Can you explain > what's happening here? I was assuming that the attributes only appeared on int return values, not struct return values. However, "getReturnInfo" is declared to be more general than the use to which I'm currently putting it, and that if it's called with an int return type without the attribute, it'll return the wrong EVT for it. I'll put them back in and pass the flags for those attributes. > >> + ?if (!CanLowerReturn) >> + ?{ > > In general, LLVM style has the opening brace on the same line as the > if, else, for, etc. > > Dan > > Whoops. From isanbard at gmail.com Mon Nov 9 15:45:26 2009 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 09 Nov 2009 21:45:26 -0000 Subject: [llvm-commits] [llvm] r86592 - /llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Message-ID: <200911092145.nA9LjR6h000359@zion.cs.uiuc.edu> Author: void Date: Mon Nov 9 15:45:26 2009 New Revision: 86592 URL: http://llvm.org/viewvc/llvm-project?rev=86592&view=rev Log: Similar to r86588, but for Darwin this time. Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp?rev=86592&r1=86591&r2=86592&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Mon Nov 9 15:45:26 2009 @@ -853,12 +853,12 @@ } } - // Print out jump tables referenced by the function. - EmitJumpTableInfo(MF.getJumpTableInfo(), MF); - // Emit post-function debug information. DW->EndFunction(&MF); + // Print out jump tables referenced by the function. + EmitJumpTableInfo(MF.getJumpTableInfo(), MF); + // We didn't modify anything. return false; } From mrs at apple.com Mon Nov 9 16:28:21 2009 From: mrs at apple.com (Mike Stump) Date: Mon, 09 Nov 2009 22:28:21 -0000 Subject: [llvm-commits] [llvm] r86600 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200911092228.nA9MSLFw002262@zion.cs.uiuc.edu> Author: mrs Date: Mon Nov 9 16:28:21 2009 New Revision: 86600 URL: http://llvm.org/viewvc/llvm-project?rev=86600&view=rev Log: Fix for 64-bit builds. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=86600&r1=86599&r2=86600&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon Nov 9 16:28:21 2009 @@ -4287,7 +4287,7 @@ EVT Ty = Arg.getValueType(); if (CI->getZExtValue() < 2) - setValue(&I, DAG.getConstant(-1U, Ty)); + setValue(&I, DAG.getConstant(-1ULL, Ty)); else setValue(&I, DAG.getConstant(0, Ty)); return 0; From gohman at apple.com Mon Nov 9 16:28:30 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 09 Nov 2009 22:28:30 -0000 Subject: [llvm-commits] [llvm] r86601 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200911092228.nA9MSUOi002281@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 16:28:30 2009 New Revision: 86601 URL: http://llvm.org/viewvc/llvm-project?rev=86601&view=rev Log: Remove an unneeded #include. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=86601&r1=86600&r2=86601&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Nov 9 16:28:30 2009 @@ -37,7 +37,6 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include -#include using namespace llvm; STATISTIC(NodesCombined , "Number of dag nodes combined"); From echristo at apple.com Mon Nov 9 16:29:14 2009 From: echristo at apple.com (Eric Christopher) Date: Mon, 9 Nov 2009 14:29:14 -0800 Subject: [llvm-commits] [llvm] r86600 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp In-Reply-To: <200911092228.nA9MSLFw002262@zion.cs.uiuc.edu> References: <200911092228.nA9MSLFw002262@zion.cs.uiuc.edu> Message-ID: <6D81D7E0-1A25-4A71-99DE-685A7096A4A5@apple.com> On Nov 9, 2009, at 2:28 PM, Mike Stump wrote: > Author: mrs > Date: Mon Nov 9 16:28:21 2009 > New Revision: 86600 > > URL: http://llvm.org/viewvc/llvm-project?rev=86600&view=rev > Log: > Fix for 64-bit builds. Thanks. Guess that did work :) Please throw a testcase in somewhere to make sure I don't break it. -eric From grosbach at apple.com Mon Nov 9 16:32:03 2009 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 09 Nov 2009 22:32:03 -0000 Subject: [llvm-commits] [llvm] r86602 - /llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Message-ID: <200911092232.nA9MW3EK002529@zion.cs.uiuc.edu> Author: grosbach Date: Mon Nov 9 16:32:03 2009 New Revision: 86602 URL: http://llvm.org/viewvc/llvm-project?rev=86602&view=rev Log: Set dynamic stack realignment to real values. Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=86602&r1=86601&r2=86602&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Mon Nov 9 16:32:03 2009 @@ -476,11 +476,7 @@ } static unsigned calculateMaxStackAlignment(const MachineFrameInfo *FFI) { - // FIXME: For now, force at least 128-bit alignment. This will push the - // nightly tester harder for making sure things work correctly. When - // we're ready to enable this for real, this goes back to starting at zero. - unsigned MaxAlign = 16; -// unsigned MaxAlign = 0; + unsigned MaxAlign = 0; for (int i = FFI->getObjectIndexBegin(), e = FFI->getObjectIndexEnd(); i != e; ++i) { @@ -508,19 +504,15 @@ bool ARMBaseRegisterInfo:: needsStackRealignment(const MachineFunction &MF) const { - // Only do this for ARM if explicitly enabled - // FIXME: Once it's passing all the tests, enable by default if (!ARMDynamicStackAlign) return false; - // FIXME: To force more brutal testing, realign whether we need to or not. - // Change this to be more selective when we turn it on for real, of course. const MachineFrameInfo *MFI = MF.getFrameInfo(); const ARMFunctionInfo *AFI = MF.getInfo(); -// unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); + unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); return (RealignStack && !AFI->isThumb1OnlyFunction() && -// (MFI->getMaxAlignment() > StackAlign) && + (MFI->getMaxAlignment() > StackAlign) && !MFI->hasVarSizedObjects()); } From sabre at nondot.org Mon Nov 9 16:32:37 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 09 Nov 2009 22:32:37 -0000 Subject: [llvm-commits] [llvm] r86603 - /llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200911092232.nA9MWbu6002598@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 16:32:36 2009 New Revision: 86603 URL: http://llvm.org/viewvc/llvm-project?rev=86603&view=rev Log: stub out a new form of BasicBlock::RemovePredecessorAndSimplify which simplifies instruction users of PHIs when the phi is eliminated. This will be moved to transforms/utils after some other refactoring. Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86603&r1=86602&r2=86603&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Mon Nov 9 16:32:36 2009 @@ -180,6 +180,68 @@ } +//===----------------------------------------------------------------------===// + + +/// RemovePredecessorAndSimplify - Like BasicBlock::removePredecessor, this +/// method is called when we're about to delete Pred as a predecessor of BB. If +/// BB contains any PHI nodes, this drops the entries in the PHI nodes for Pred. +/// +/// Unlike the removePredecessor method, this attempts to simplify uses of PHI +/// nodes that collapse into identity values. For example, if we have: +/// x = phi(1, 0, 0, 0) +/// y = and x, z +/// +/// .. and delete the predecessor corresponding to the '1', this will attempt to +/// recursively fold the and to 0. +static void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred, + TargetData *TD) { + // This only adjusts blocks with PHI nodes. + if (!isa(BB->begin())) + return; + + // Remove the entries for Pred from the PHI nodes in BB, but do not simplify + // them down. This will leave us with single entry phi nodes and other phis + // that can be removed. + //BB->removePredecessor(Pred, true); + BB->removePredecessor(Pred, true); + + WeakVH PhiIt = &BB->front(); + while (PHINode *PN = dyn_cast(PhiIt)) { + PhiIt = &*++BasicBlock::iterator(cast(PhiIt)); + + Value *PNV = PN->hasConstantValue(); + if (PNV == 0) continue; + + assert(PNV != PN && "hasConstantValue broken"); + + // If we're able to simplify the phi to a constant, simplify it into its + // uses. + while (!PN->use_empty()) { + // Update the instruction to use the new value. + Use &U = PN->use_begin().getUse(); + Instruction *User = cast(U.getUser()); + U = PNV; + + // See if we can simplify it (constant folding). + if (Constant *C = ConstantFoldInstruction(User, TD)) { + User->replaceAllUsesWith(C); + User->eraseFromParent(); + } + } + + PN->replaceAllUsesWith(PNV); + PN->eraseFromParent(); + + // If recursive simplification ended up deleting the next PHI node we would + // iterate to, then our iterator is invalid, restart scanning from the top + // of the block. + if (PhiIt == 0) PhiIt = &BB->front(); + } +} + +//===----------------------------------------------------------------------===// + /// FindLoopHeaders - We do not want jump threading to turn proper loop /// structures into irreducible loops. Doing this breaks up the loop nesting @@ -411,7 +473,7 @@ TerminatorInst *BBTerm = BB->getTerminator(); for (unsigned i = 0, e = BBTerm->getNumSuccessors(); i != e; ++i) { if (i == BestSucc) continue; - BBTerm->getSuccessor(i)->removePredecessor(BB); + RemovePredecessorAndSimplify(BBTerm->getSuccessor(i), BB, TD); } DEBUG(errs() << " In block '" << BB->getName() @@ -868,8 +930,6 @@ if (LoopHeaders.count(BB)) return false; - - SmallVector, 8> PredValues; if (!ComputeValueKnownInPredecessors(CondInst, BB, PredValues)) return false; @@ -1153,7 +1213,7 @@ TerminatorInst *PredTerm = PredBB->getTerminator(); for (unsigned i = 0, e = PredTerm->getNumSuccessors(); i != e; ++i) if (PredTerm->getSuccessor(i) == BB) { - BB->removePredecessor(PredBB); + RemovePredecessorAndSimplify(BB, PredBB, TD); PredTerm->setSuccessor(i, NewBB); } @@ -1283,7 +1343,7 @@ // PredBB no longer jumps to BB, remove entries in the PHI node for the edge // that we nuked. - BB->removePredecessor(PredBB); + RemovePredecessorAndSimplify(BB, PredBB, TD); // Remove the unconditional branch at the end of the PredBB block. OldPredBranch->eraseFromParent(); From grosbach at apple.com Mon Nov 9 16:32:40 2009 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 09 Nov 2009 22:32:40 -0000 Subject: [llvm-commits] [llvm] r86604 - /llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Message-ID: <200911092232.nA9MWeAk002613@zion.cs.uiuc.edu> Author: grosbach Date: Mon Nov 9 16:32:40 2009 New Revision: 86604 URL: http://llvm.org/viewvc/llvm-project?rev=86604&view=rev Log: Enable dynamic stack realignment by default. Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=86604&r1=86603&r2=86604&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Mon Nov 9 16:32:40 2009 @@ -45,7 +45,7 @@ cl::desc("Reuse repeated frame index values")); static cl::opt -ARMDynamicStackAlign("arm-dynamic-stack-alignment", cl::Hidden, cl::init(false), +ARMDynamicStackAlign("arm-dynamic-stack-alignment", cl::Hidden, cl::init(true), cl::desc("Dynamically re-align the stack as needed")); unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum, From jyasskin at google.com Mon Nov 9 16:34:19 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Mon, 09 Nov 2009 22:34:19 -0000 Subject: [llvm-commits] [llvm] r86606 - in /llvm/trunk: include/llvm/ExecutionEngine/ExecutionEngine.h include/llvm/ExecutionEngine/JITMemoryManager.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngine/JIT/JIT.h lib/ExecutionEngine/JIT/JITEmitter.cpp lib/ExecutionEngine/JIT/JITMemoryManager.cpp unittests/ExecutionEngine/JIT/JITTest.cpp Message-ID: <200911092234.nA9MYKSQ002783@zion.cs.uiuc.edu> Author: jyasskin Date: Mon Nov 9 16:34:19 2009 New Revision: 86606 URL: http://llvm.org/viewvc/llvm-project?rev=86606&view=rev Log: Remove dlsym stubs, with Nate Begeman's permission. Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp llvm/trunk/lib/ExecutionEngine/JIT/JIT.h llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=86606&r1=86605&r2=86606&view=diff ============================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h (original) +++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Mon Nov 9 16:34:19 2009 @@ -91,7 +91,6 @@ bool CompilingLazily; bool GVCompilationDisabled; bool SymbolSearchingDisabled; - bool DlsymStubsEnabled; friend class EngineBuilder; // To allow access to JITCtor and InterpCtor. @@ -369,15 +368,7 @@ bool isSymbolSearchingDisabled() const { return SymbolSearchingDisabled; } - - /// EnableDlsymStubs - - void EnableDlsymStubs(bool Enabled = true) { - DlsymStubsEnabled = Enabled; - } - bool areDlsymStubsEnabled() const { - return DlsymStubsEnabled; - } - + /// InstallLazyFunctionCreator - If an unknown function is needed, the /// specified function pointer is invoked to create it. If it returns null, /// the JIT will abort. Modified: llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h?rev=86606&r1=86605&r2=86606&view=diff ============================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h (original) +++ llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h Mon Nov 9 16:34:19 2009 @@ -71,17 +71,6 @@ /// return a pointer to its base. virtual uint8_t *getGOTBase() const = 0; - /// SetDlsymTable - If the JIT must be able to relocate stubs after they have - /// been emitted, potentially because they are being copied to a process - /// where external symbols live at different addresses than in the JITing - /// process, allocate a table with sufficient information to do so. - virtual void SetDlsymTable(void *ptr) = 0; - - /// getDlsymTable - If this is managing a table of entries so that stubs to - /// external symbols can be later relocated, this method should return a - /// pointer to it. - virtual void *getDlsymTable() const = 0; - /// NeedsExactSize - If the memory manager requires to know the size of the /// objects to be emitted bool NeedsExactSize() const { Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=86606&r1=86605&r2=86606&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Mon Nov 9 16:34:19 2009 @@ -52,7 +52,6 @@ CompilingLazily = false; GVCompilationDisabled = false; SymbolSearchingDisabled = false; - DlsymStubsEnabled = false; Modules.push_back(P); assert(P && "ModuleProvider is null?"); } Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=86606&r1=86605&r2=86606&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Mon Nov 9 16:34:19 2009 @@ -613,11 +613,6 @@ // the stub with real address of the function. updateFunctionStub(PF); } - - // If the JIT is configured to emit info so that dlsym can be used to - // rewrite stubs to external globals, do so now. - if (areDlsymStubsEnabled() && !isCompilingLazily()) - updateDlsymStubTable(); } /// getPointerToFunction - This method is used to get the address of the @@ -660,8 +655,7 @@ } if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) { - bool AbortOnFailure = - !areDlsymStubsEnabled() && !F->hasExternalWeakLinkage(); + bool AbortOnFailure = !F->hasExternalWeakLinkage(); void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure); addGlobalMapping(F, Addr); return Addr; @@ -690,7 +684,7 @@ return (void*)&__dso_handle; #endif Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(GV->getName()); - if (Ptr == 0 && !areDlsymStubsEnabled()) { + if (Ptr == 0) { llvm_report_error("Could not resolve external global address: " +GV->getName()); } Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.h?rev=86606&r1=86605&r2=86606&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.h (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.h Mon Nov 9 16:34:19 2009 @@ -195,7 +195,6 @@ TargetMachine &tm); void runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked); void updateFunctionStub(Function *F); - void updateDlsymStubTable(); protected: Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=86606&r1=86605&r2=86606&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Mon Nov 9 16:34:19 2009 @@ -369,10 +369,6 @@ // the stub is unused. DenseMap > StubFnRefs; - // ExtFnStubs - A map of external function names to stubs which have entries - // in the JITResolver's ExternalFnToStubMap. - StringMap ExtFnStubs; - DebugLocTuple PrevDLT; public: @@ -461,10 +457,6 @@ /// deallocateMemForFunction to also remove stubs no longer referenced. void AddStubToCurrentFunction(void *Stub); - /// getExternalFnStubs - Accessor for the JIT to find stubs emitted for - /// MachineRelocations that reference external functions by name. - const StringMap &getExternalFnStubs() const { return ExtFnStubs; } - virtual void processDebugLoc(DebugLoc DL, bool BeforePrintingInsn); virtual void emitLabel(uint64_t LabelID) { @@ -536,10 +528,8 @@ Actual = TheJIT->getPointerToFunction(F); // If we resolved the symbol to a null address (eg. a weak external) - // don't emit a stub. Return a null pointer to the application. If dlsym - // stubs are enabled, not being able to resolve the address is not - // meaningful. - if (!Actual && !TheJIT->areDlsymStubsEnabled()) return 0; + // don't emit a stub. Return a null pointer to the application. + if (!Actual) return 0; } // Codegen a new stub, calling the lazy resolver or the actual address of the @@ -758,10 +748,9 @@ if (ResultPtr) return ResultPtr; // If this is an external function pointer, we can force the JIT to - // 'compile' it, which really just adds it to the map. In dlsym mode, - // external functions are forced through a stub, regardless of reloc type. + // 'compile' it, which really just adds it to the map. if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode() && - !MayNeedFarStub && !TheJIT->areDlsymStubsEnabled()) + !MayNeedFarStub) return TheJIT->getPointerToFunction(F); // Okay, the function has not been compiled yet, if the target callback @@ -1112,16 +1101,7 @@ // If the target REALLY wants a stub for this function, emit it now. if (MR.mayNeedFarStub()) { - if (!TheJIT->areDlsymStubsEnabled()) { - ResultPtr = Resolver.getExternalFunctionStub(ResultPtr); - } else { - void *&Stub = ExtFnStubs[MR.getExternalSymbol()]; - if (!Stub) { - Stub = Resolver.getExternalFunctionStub((void *)&Stub); - AddStubToCurrentFunction(Stub); - } - ResultPtr = Stub; - } + ResultPtr = Resolver.getExternalFunctionStub(ResultPtr); } } else if (MR.isGlobalValue()) { ResultPtr = getPointerToGlobal(MR.getGlobalValue(), @@ -1335,19 +1315,10 @@ StubFnRefs.erase(Stub); // Invalidate the stub. If it is a GV stub, update the JIT's global - // mapping for that GV to zero, otherwise, search the string map of - // external function names to stubs and remove the entry for this stub. + // mapping for that GV to zero. GlobalValue *GV = Resolver.invalidateStub(Stub); if (GV) { TheJIT->updateGlobalMapping(GV, 0); - } else { - for (StringMapIterator i = ExtFnStubs.begin(), - e = ExtFnStubs.end(); i != e; ++i) { - if (i->second == Stub) { - ExtFnStubs.erase(i); - break; - } - } } } } @@ -1588,92 +1559,6 @@ getJITInfo().emitFunctionStubAtAddr(F, Addr, Stub, *getCodeEmitter()); } -/// updateDlsymStubTable - Emit the data necessary to relocate the stubs -/// that were emitted during code generation. -/// -void JIT::updateDlsymStubTable() { - assert(isa(JCE) && "Unexpected MCE?"); - JITEmitter *JE = cast(getCodeEmitter()); - - SmallVector GVs; - SmallVector Ptrs; - const StringMap &ExtFns = JE->getExternalFnStubs(); - - JE->getJITResolver().getRelocatableGVs(GVs, Ptrs); - - unsigned nStubs = GVs.size() + ExtFns.size(); - - // If there are no relocatable stubs, return. - if (nStubs == 0) - return; - - // If there are no new relocatable stubs, return. - void *CurTable = JE->getMemMgr()->getDlsymTable(); - if (CurTable && (*(unsigned *)CurTable == nStubs)) - return; - - // Calculate the size of the stub info - unsigned offset = 4 + 4 * nStubs + sizeof(intptr_t) * nStubs; - - SmallVector Offsets; - for (unsigned i = 0; i != GVs.size(); ++i) { - Offsets.push_back(offset); - offset += GVs[i]->getName().size() + 1; - } - for (StringMapConstIterator i = ExtFns.begin(), e = ExtFns.end(); - i != e; ++i) { - Offsets.push_back(offset); - offset += strlen(i->first()) + 1; - } - - // Allocate space for the new "stub", which contains the dlsym table. - JE->startGVStub(0, offset, 4); - - // Emit the number of records - JE->emitInt32(nStubs); - - // Emit the string offsets - for (unsigned i = 0; i != nStubs; ++i) - JE->emitInt32(Offsets[i]); - - // Emit the pointers. Verify that they are at least 2-byte aligned, and set - // the low bit to 0 == GV, 1 == Function, so that the client code doing the - // relocation can write the relocated pointer at the appropriate place in - // the stub. - for (unsigned i = 0; i != GVs.size(); ++i) { - intptr_t Ptr = (intptr_t)Ptrs[i]; - assert((Ptr & 1) == 0 && "Stub pointers must be at least 2-byte aligned!"); - - if (isa(GVs[i])) - Ptr |= (intptr_t)1; - - if (sizeof(Ptr) == 8) - JE->emitInt64(Ptr); - else - JE->emitInt32(Ptr); - } - for (StringMapConstIterator i = ExtFns.begin(), e = ExtFns.end(); - i != e; ++i) { - intptr_t Ptr = (intptr_t)i->second | 1; - - if (sizeof(Ptr) == 8) - JE->emitInt64(Ptr); - else - JE->emitInt32(Ptr); - } - - // Emit the strings. - for (unsigned i = 0; i != GVs.size(); ++i) - JE->emitString(GVs[i]->getName()); - for (StringMapConstIterator i = ExtFns.begin(), e = ExtFns.end(); - i != e; ++i) - JE->emitString(i->first()); - - // Tell the JIT memory manager where it is. The JIT Memory Manager will - // deallocate space for the old one, if one existed. - JE->getMemMgr()->SetDlsymTable(JE->finishGVStub(0)); -} - /// freeMachineCodeForFunction - release machine code memory for given Function. /// void JIT::freeMachineCodeForFunction(Function *F) { Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp?rev=86606&r1=86605&r2=86606&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp Mon Nov 9 16:34:19 2009 @@ -296,7 +296,6 @@ MemoryRangeHeader *CurBlock; uint8_t *GOTBase; // Target Specific reserved memory - void *DlsymTable; // Stub external symbol information public: DefaultJITMemoryManager(); ~DefaultJITMemoryManager(); @@ -318,7 +317,6 @@ static const size_t DefaultSizeThreshold; void AllocateGOT(); - void SetDlsymTable(void *); // Testing methods. virtual bool CheckInvariants(std::string &ErrorStr); @@ -469,10 +467,6 @@ return GOTBase; } - void *getDlsymTable() const { - return DlsymTable; - } - void deallocateBlock(void *Block) { // Find the block that is allocated for this function. MemoryRangeHeader *MemRange = static_cast(Block) - 1; @@ -599,7 +593,6 @@ FreeMemoryList = Mem0; GOTBase = NULL; - DlsymTable = NULL; } void DefaultJITMemoryManager::AllocateGOT() { @@ -608,10 +601,6 @@ HasGOT = true; } -void DefaultJITMemoryManager::SetDlsymTable(void *ptr) { - DlsymTable = ptr; -} - DefaultJITMemoryManager::~DefaultJITMemoryManager() { for (unsigned i = 0, e = CodeSlabs.size(); i != e; ++i) sys::Memory::ReleaseRWX(CodeSlabs[i]); Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=86606&r1=86605&r2=86606&view=diff ============================================================================== --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original) +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Mon Nov 9 16:34:19 2009 @@ -68,8 +68,6 @@ virtual void setPoisonMemory(bool poison) { Base->setPoisonMemory(poison); } virtual void AllocateGOT() { Base->AllocateGOT(); } virtual uint8_t *getGOTBase() const { return Base->getGOTBase(); } - virtual void SetDlsymTable(void *ptr) { Base->SetDlsymTable(ptr); } - virtual void *getDlsymTable() const { return Base->getDlsymTable(); } struct StartFunctionBodyCall { StartFunctionBodyCall(uint8_t *Result, const Function *F, uintptr_t ActualSize, uintptr_t ActualSizeResult) @@ -303,7 +301,6 @@ ConstantInt::get(TypeBuilder::get(Context), 7)); Builder.CreateRet(result); - TheJIT->EnableDlsymStubs(false); TheJIT->DisableLazyCompilation(true); int (*TestFunctionPtr)() = reinterpret_cast( (intptr_t)TheJIT->getPointerToFunction(TestFunction)); From anton at korobeynikov.info Mon Nov 9 16:37:48 2009 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Tue, 10 Nov 2009 01:37:48 +0300 Subject: [llvm-commits] [llvm] r86604 - /llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp In-Reply-To: <200911092232.nA9MWeAk002613@zion.cs.uiuc.edu> References: <200911092232.nA9MWeAk002613@zion.cs.uiuc.edu> Message-ID: <1257806268.7975.104.camel@aslstation> Hello, Jim > static cl::opt > -ARMDynamicStackAlign("arm-dynamic-stack-alignment", cl::Hidden, cl::init(false), > +ARMDynamicStackAlign("arm-dynamic-stack-alignment", cl::Hidden, cl::init(true), > cl::desc("Dynamically re-align the stack as needed")); We already have generic 'RealignStack' flag. Please use it. -- With best regards, Anton Korobeynikov. Faculty of Mathematics & Mechanics, Saint Petersburg State University. From sabre at nondot.org Mon Nov 9 16:57:59 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 09 Nov 2009 22:57:59 -0000 Subject: [llvm-commits] [llvm] r86613 - in /llvm/trunk: include/llvm/Analysis/InstructionSimplify.h lib/Analysis/CMakeLists.txt lib/Analysis/InstructionSimplify.cpp Message-ID: <200911092257.nA9MvxAt004112@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 16:57:59 2009 New Revision: 86613 URL: http://llvm.org/viewvc/llvm-project?rev=86613&view=rev Log: stub out a new libanalysis "instruction simplify" interface that takes decimated instructions and applies identities to them. This is pretty minimal at this point, but I plan to pull some instcombine logic out into these and similar routines. Added: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h llvm/trunk/lib/Analysis/InstructionSimplify.cpp Modified: llvm/trunk/lib/Analysis/CMakeLists.txt Added: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionSimplify.h?rev=86613&view=auto ============================================================================== --- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h (added) +++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Mon Nov 9 16:57:59 2009 @@ -0,0 +1,37 @@ +//===-- InstructionSimplify.h - Fold instructions into simpler forms ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares routines for folding instructions into simpler forms that +// do not require creating new instructions. For example, this does constant +// folding, and can handle identities like (X&0)->0. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H +#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H + +namespace llvm { + class Value; + class TargetData; + + /// SimplifyCompare - Given operands for a CmpInst, see if we can + /// fold the result. If not, this returns null. + Value *SimplifyCompare(unsigned Predicate, Value *LHS, Value *RHS, + const TargetData *TD = 0); + + + /// SimplifyBinOp - Given operands for a BinaryOperator, see if we can + /// fold the result. If not, this returns null. + Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, + const TargetData *TD = 0); + +} // end namespace llvm + +#endif + Modified: llvm/trunk/lib/Analysis/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=86613&r1=86612&r2=86613&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/CMakeLists.txt (original) +++ llvm/trunk/lib/Analysis/CMakeLists.txt Mon Nov 9 16:57:59 2009 @@ -15,6 +15,7 @@ IVUsers.cpp InlineCost.cpp InstCount.cpp + InstructionSimplify.cpp Interval.cpp IntervalPartition.cpp LibCallAliasAnalysis.cpp Added: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=86613&view=auto ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (added) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Mon Nov 9 16:57:59 2009 @@ -0,0 +1,57 @@ +//===- InstructionSimplify.cpp - Fold instruction operands ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements routines for folding instructions into simpler forms +// that do not require creating new instructions. For example, this does +// constant folding, and can handle identities like (X&0)->0. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Instructions.h" +using namespace llvm; + + +/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can +/// fold the result. If not, this returns null. +Value *llvm::SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, + const TargetData *TD) { + if (Constant *CLHS = dyn_cast(LHS)) + if (Constant *CRHS = dyn_cast(RHS)) { + Constant *COps[] = {CLHS, CRHS}; + return ConstantFoldInstOperands(Opcode, LHS->getType(), COps, 2, TD); + } + return 0; +} + + +/// SimplifyCompare - Given operands for a CmpInst, see if we can +/// fold the result. +Value *llvm::SimplifyCompare(unsigned Predicate, Value *LHS, Value *RHS, + const TargetData *TD) { + CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate; + + if (Constant *CLHS = dyn_cast(LHS)) + if (Constant *CRHS = dyn_cast(RHS)) { + Constant *COps[] = {CLHS, CRHS}; + return ConstantFoldCompareInstOperands(Pred, COps, 2, TD); + } + + // If this is an integer compare and the LHS and RHS are the same, fold it. + if (LHS == RHS) + if (isa(LHS->getType()) || isa(LHS->getType())) { + if (ICmpInst::isTrueWhenEqual(Pred)) + return ConstantInt::getTrue(LHS->getContext()); + else + return ConstantInt::getFalse(LHS->getContext()); + } + return 0; +} + From grosbach at apple.com Mon Nov 9 16:59:01 2009 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 09 Nov 2009 22:59:01 -0000 Subject: [llvm-commits] [llvm] r86614 - /llvm/trunk/test/CodeGen/Thumb2/large-stack.ll Message-ID: <200911092259.nA9Mx1RR004163@zion.cs.uiuc.edu> Author: grosbach Date: Mon Nov 9 16:59:01 2009 New Revision: 86614 URL: http://llvm.org/viewvc/llvm-project?rev=86614&view=rev Log: Update test Modified: llvm/trunk/test/CodeGen/Thumb2/large-stack.ll Modified: llvm/trunk/test/CodeGen/Thumb2/large-stack.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/large-stack.ll?rev=86614&r1=86613&r2=86614&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/large-stack.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/large-stack.ll Mon Nov 9 16:59:01 2009 @@ -18,7 +18,7 @@ define i32 @test3() { ; CHECK: test3: ; CHECK: sub.w sp, sp, #805306368 -; CHECK: sub sp, #4 * 4 +; CHECK: sub sp, #6 * 4 %retval = alloca i32, align 4 %tmp = alloca i32, align 4 %a = alloca [805306369 x i8], align 16 From sabre at nondot.org Mon Nov 9 17:00:14 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 09 Nov 2009 23:00:14 -0000 Subject: [llvm-commits] [llvm] r86616 - /llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200911092300.nA9N0Euu004227@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 17:00:14 2009 New Revision: 86616 URL: http://llvm.org/viewvc/llvm-project?rev=86616&view=rev Log: use instructionsimplify instead of a weak clone of ad-hoc folding stuff. Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86616&r1=86615&r2=86616&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Mon Nov 9 17:00:14 2009 @@ -17,6 +17,7 @@ #include "llvm/LLVMContext.h" #include "llvm/Pass.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/SSAUpdater.h" @@ -203,7 +204,6 @@ // Remove the entries for Pred from the PHI nodes in BB, but do not simplify // them down. This will leave us with single entry phi nodes and other phis // that can be removed. - //BB->removePredecessor(Pred, true); BB->removePredecessor(Pred, true); WeakVH PhiIt = &BB->front(); @@ -266,26 +266,6 @@ LoopHeaders.insert(const_cast(Edges[i].second)); } -/// GetResultOfComparison - Given an icmp/fcmp predicate and the left and right -/// hand sides of the compare instruction, try to determine the result. If the -/// result can not be determined, a null pointer is returned. -static Constant *GetResultOfComparison(CmpInst::Predicate pred, - Value *LHS, Value *RHS) { - if (Constant *CLHS = dyn_cast(LHS)) - if (Constant *CRHS = dyn_cast(RHS)) - return ConstantExpr::getCompare(pred, CLHS, CRHS); - - if (LHS == RHS) - if (isa(LHS->getType()) || isa(LHS->getType())) { - if (ICmpInst::isTrueWhenEqual(pred)) - return ConstantInt::getTrue(LHS->getContext()); - else - return ConstantInt::getFalse(LHS->getContext()); - } - return 0; -} - - /// ComputeValueKnownInPredecessors - Given a basic block BB and a value V, see /// if we can infer that the value is a known ConstantInt in any of our /// predecessors. If so, return the known list of value and pred BB in the @@ -374,7 +354,7 @@ Value *LHS = PN->getIncomingValue(i); Value *RHS = Cmp->getOperand(1)->DoPHITranslation(BB, PredBB); - Constant *Res = GetResultOfComparison(Cmp->getPredicate(), LHS, RHS); + Value *Res = SimplifyCompare(Cmp->getPredicate(), LHS, RHS); if (Res == 0) continue; if (isa(Res)) From daniel at zuster.org Mon Nov 9 17:05:44 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 09 Nov 2009 23:05:44 -0000 Subject: [llvm-commits] [llvm] r86618 - /llvm/trunk/include/llvm/ADT/StringSwitch.h Message-ID: <200911092305.nA9N5jlM004456@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Nov 9 17:05:44 2009 New Revision: 86618 URL: http://llvm.org/viewvc/llvm-project?rev=86618&view=rev Log: Add StringSwitch::Cases overloads, for matching multiple strings to a single value. Modified: llvm/trunk/include/llvm/ADT/StringSwitch.h Modified: llvm/trunk/include/llvm/ADT/StringSwitch.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringSwitch.h?rev=86618&r1=86617&r2=86618&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/StringSwitch.h (original) +++ llvm/trunk/include/llvm/ADT/StringSwitch.h Mon Nov 9 17:05:44 2009 @@ -65,6 +65,25 @@ return *this; } + template + StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], + const T& Value) { + return Case(S0, Value).Case(S1, Value); + } + + template + StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], + const char (&S2)[N2], const T& Value) { + return Case(S0, Value).Case(S1, Value).Case(S2, Value); + } + + template + StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], + const char (&S2)[N2], const char (&S3)[N3], + const T& Value) { + return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value); + } + T Default(const T& Value) { if (ResultKnown) return Result; From sabre at nondot.org Mon Nov 9 17:06:58 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 09 Nov 2009 23:06:58 -0000 Subject: [llvm-commits] [llvm] r86619 - in /llvm/trunk: include/llvm/Analysis/ConstantFolding.h lib/Analysis/ConstantFolding.cpp lib/Analysis/InstructionSimplify.cpp lib/Analysis/ScalarEvolution.cpp lib/Transforms/Utils/CloneFunction.cpp Message-ID: <200911092306.nA9N6wHx004509@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 17:06:58 2009 New Revision: 86619 URL: http://llvm.org/viewvc/llvm-project?rev=86619&view=rev Log: fix ConstantFoldCompareInstOperands to take the LHS/RHS as individual operands instead of taking a temporary array Modified: llvm/trunk/include/llvm/Analysis/ConstantFolding.h llvm/trunk/lib/Analysis/ConstantFolding.cpp llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/lib/Analysis/ScalarEvolution.cpp llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Modified: llvm/trunk/include/llvm/Analysis/ConstantFolding.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ConstantFolding.h?rev=86619&r1=86618&r2=86619&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ConstantFolding.h (original) +++ llvm/trunk/include/llvm/Analysis/ConstantFolding.h Mon Nov 9 17:06:58 2009 @@ -55,7 +55,7 @@ /// returns a constant expression of the specified operands. /// Constant *ConstantFoldCompareInstOperands(unsigned Predicate, - Constant *const *Ops, unsigned NumOps, + Constant *LHS, Constant *RHS, const TargetData *TD = 0); /// ConstantFoldLoadFromConstPtr - Return the value that a load from C would Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=86619&r1=86618&r2=86619&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Mon Nov 9 17:06:58 2009 @@ -655,8 +655,8 @@ return 0; // All operands not constant! if (const CmpInst *CI = dyn_cast(I)) - return ConstantFoldCompareInstOperands(CI->getPredicate(), - Ops.data(), Ops.size(), TD); + return ConstantFoldCompareInstOperands(CI->getPredicate(), Ops[0], Ops[1], + TD); if (const LoadInst *LI = dyn_cast(I)) return ConstantFoldLoadInst(LI, TD); @@ -675,8 +675,8 @@ Ops.push_back(cast(*i)); if (CE->isCompare()) - return ConstantFoldCompareInstOperands(CE->getPredicate(), - Ops.data(), Ops.size(), TD); + return ConstantFoldCompareInstOperands(CE->getPredicate(), Ops[0], Ops[1], + TD); return ConstantFoldInstOperands(CE->getOpcode(), CE->getType(), Ops.data(), Ops.size(), TD); } @@ -806,8 +806,7 @@ /// returns a constant expression of the specified operands. /// Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate, - Constant *const *Ops, - unsigned NumOps, + Constant *Ops0, Constant *Ops1, const TargetData *TD) { // fold: icmp (inttoptr x), null -> icmp x, 0 // fold: icmp (ptrtoint x), 0 -> icmp x, null @@ -816,16 +815,16 @@ // // ConstantExpr::getCompare cannot do this, because it doesn't have TD // around to know if bit truncation is happening. - if (ConstantExpr *CE0 = dyn_cast(Ops[0])) { - if (TD && Ops[1]->isNullValue()) { + if (ConstantExpr *CE0 = dyn_cast(Ops0)) { + if (TD && Ops1->isNullValue()) { const Type *IntPtrTy = TD->getIntPtrType(CE0->getContext()); if (CE0->getOpcode() == Instruction::IntToPtr) { // Convert the integer value to the right size to ensure we get the // proper extension or truncation. Constant *C = ConstantExpr::getIntegerCast(CE0->getOperand(0), IntPtrTy, false); - Constant *NewOps[] = { C, Constant::getNullValue(C->getType()) }; - return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD); + Constant *Null = Constant::getNullValue(C->getType()); + return ConstantFoldCompareInstOperands(Predicate, C, Null, TD); } // Only do this transformation if the int is intptrty in size, otherwise @@ -833,13 +832,12 @@ if (CE0->getOpcode() == Instruction::PtrToInt && CE0->getType() == IntPtrTy) { Constant *C = CE0->getOperand(0); - Constant *NewOps[] = { C, Constant::getNullValue(C->getType()) }; - // FIXME! - return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD); + Constant *Null = Constant::getNullValue(C->getType()); + return ConstantFoldCompareInstOperands(Predicate, C, Null, TD); } } - if (ConstantExpr *CE1 = dyn_cast(Ops[1])) { + if (ConstantExpr *CE1 = dyn_cast(Ops1)) { if (TD && CE0->getOpcode() == CE1->getOpcode()) { const Type *IntPtrTy = TD->getIntPtrType(CE0->getContext()); @@ -850,24 +848,21 @@ IntPtrTy, false); Constant *C1 = ConstantExpr::getIntegerCast(CE1->getOperand(0), IntPtrTy, false); - Constant *NewOps[] = { C0, C1 }; - return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD); + return ConstantFoldCompareInstOperands(Predicate, C0, C1, TD); } // Only do this transformation if the int is intptrty in size, otherwise // there is a truncation or extension that we aren't modeling. if ((CE0->getOpcode() == Instruction::PtrToInt && CE0->getType() == IntPtrTy && - CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType())) { - Constant *NewOps[] = { - CE0->getOperand(0), CE1->getOperand(0) - }; - return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD); - } + CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType())) + return ConstantFoldCompareInstOperands(Predicate, CE0->getOperand(0), + CE1->getOperand(0), TD); } } } - return ConstantExpr::getCompare(Predicate, Ops[0], Ops[1]); + + return ConstantExpr::getCompare(Predicate, Ops0, Ops1); } Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=86619&r1=86618&r2=86619&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Mon Nov 9 17:06:58 2009 @@ -39,10 +39,8 @@ CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate; if (Constant *CLHS = dyn_cast(LHS)) - if (Constant *CRHS = dyn_cast(RHS)) { - Constant *COps[] = {CLHS, CRHS}; - return ConstantFoldCompareInstOperands(Pred, COps, 2, TD); - } + if (Constant *CRHS = dyn_cast(RHS)) + return ConstantFoldCompareInstOperands(Pred, CLHS, CRHS, TD); // If this is an integer compare and the LHS and RHS are the same, fold it. if (LHS == RHS) Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=86619&r1=86618&r2=86619&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Nov 9 17:06:58 2009 @@ -3826,11 +3826,10 @@ } if (const CmpInst *CI = dyn_cast(I)) - return ConstantFoldCompareInstOperands(CI->getPredicate(), - &Operands[0], Operands.size()); - else - return ConstantFoldInstOperands(I->getOpcode(), I->getType(), - &Operands[0], Operands.size()); + return ConstantFoldCompareInstOperands(CI->getPredicate(), Operands[0], + Operands[1]); + return ConstantFoldInstOperands(I->getOpcode(), I->getType(), + &Operands[0], Operands.size()); } /// getConstantEvolutionLoopExitValue - If we know that the specified Phi is @@ -4037,7 +4036,7 @@ Constant *C; if (const CmpInst *CI = dyn_cast(I)) C = ConstantFoldCompareInstOperands(CI->getPredicate(), - &Operands[0], Operands.size()); + Operands[0], Operands[1]); else C = ConstantFoldInstOperands(I->getOpcode(), I->getType(), &Operands[0], Operands.size()); Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=86619&r1=86618&r2=86619&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Mon Nov 9 17:06:58 2009 @@ -331,8 +331,8 @@ return 0; // All operands not constant! if (const CmpInst *CI = dyn_cast(I)) - return ConstantFoldCompareInstOperands(CI->getPredicate(), - &Ops[0], Ops.size(), TD); + return ConstantFoldCompareInstOperands(CI->getPredicate(), Ops[0], Ops[1], + TD); if (const LoadInst *LI = dyn_cast(I)) if (ConstantExpr *CE = dyn_cast(Ops[0])) From mrs at apple.com Mon Nov 9 17:10:49 2009 From: mrs at apple.com (Mike Stump) Date: Mon, 09 Nov 2009 23:10:49 -0000 Subject: [llvm-commits] [llvm] r86620 - /llvm/trunk/test/CodeGen/X86/object-size.ll Message-ID: <200911092310.nA9NAn5d004635@zion.cs.uiuc.edu> Author: mrs Date: Mon Nov 9 17:10:49 2009 New Revision: 86620 URL: http://llvm.org/viewvc/llvm-project?rev=86620&view=rev Log: Add testcase for recent checkin. Added: llvm/trunk/test/CodeGen/X86/object-size.ll Added: llvm/trunk/test/CodeGen/X86/object-size.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/object-size.ll?rev=86620&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/object-size.ll (added) +++ llvm/trunk/test/CodeGen/X86/object-size.ll Mon Nov 9 17:10:49 2009 @@ -0,0 +1,55 @@ +; RUN: llc -O0 < %s -march=x86-64 | FileCheck %s -check-prefix=X64 + +; ModuleID = 'ts.c' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-apple-darwin10.0" + + at p = common global i8* null, align 8 ; [#uses=4] + at .str = private constant [3 x i8] c"Hi\00" ; <[3 x i8]*> [#uses=1] + +define void @bar() nounwind ssp { +entry: + %tmp = load i8** @p ; [#uses=1] + %0 = call i64 @llvm.objectsize.i64(i8* %tmp, i32 0) ; [#uses=1] + %cmp = icmp ne i64 %0, -1 ; [#uses=1] +; X64: movq $-1, %rax +; X64: cmpq $-1, %rax + br i1 %cmp, label %cond.true, label %cond.false + +cond.true: ; preds = %entry + %tmp1 = load i8** @p ; [#uses=1] + %tmp2 = load i8** @p ; [#uses=1] + %1 = call i64 @llvm.objectsize.i64(i8* %tmp2, i32 1) ; [#uses=1] + %call = call i8* @__strcpy_chk(i8* %tmp1, i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i64 %1) ssp ; [#uses=1] + br label %cond.end + +cond.false: ; preds = %entry + %tmp3 = load i8** @p ; [#uses=1] + %call4 = call i8* @__inline_strcpy_chk(i8* %tmp3, i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0)) ssp ; [#uses=1] + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i8* [ %call, %cond.true ], [ %call4, %cond.false ] ; [#uses=0] + ret void +} + +declare i64 @llvm.objectsize.i64(i8*, i32) nounwind readonly + +declare i8* @__strcpy_chk(i8*, i8*, i64) ssp + +define internal i8* @__inline_strcpy_chk(i8* %__dest, i8* %__src) nounwind ssp { +entry: + %retval = alloca i8* ; [#uses=2] + %__dest.addr = alloca i8* ; [#uses=3] + %__src.addr = alloca i8* ; [#uses=2] + store i8* %__dest, i8** %__dest.addr + store i8* %__src, i8** %__src.addr + %tmp = load i8** %__dest.addr ; [#uses=1] + %tmp1 = load i8** %__src.addr ; [#uses=1] + %tmp2 = load i8** %__dest.addr ; [#uses=1] + %0 = call i64 @llvm.objectsize.i64(i8* %tmp2, i32 1) ; [#uses=1] + %call = call i8* @__strcpy_chk(i8* %tmp, i8* %tmp1, i64 %0) ssp ; [#uses=1] + store i8* %call, i8** %retval + %1 = load i8** %retval ; [#uses=1] + ret i8* %1 +} From grosbach at apple.com Mon Nov 9 17:11:45 2009 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 09 Nov 2009 23:11:45 -0000 Subject: [llvm-commits] [llvm] r86621 - /llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Message-ID: <200911092311.nA9NBj4a004671@zion.cs.uiuc.edu> Author: grosbach Date: Mon Nov 9 17:11:45 2009 New Revision: 86621 URL: http://llvm.org/viewvc/llvm-project?rev=86621&view=rev Log: Now that the default is 'enabled,' a separate command line option for ARM is not necessary. Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=86621&r1=86620&r2=86621&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Mon Nov 9 17:11:45 2009 @@ -44,10 +44,6 @@ ReuseFrameIndexVals("arm-reuse-frame-index-vals", cl::Hidden, cl::init(true), cl::desc("Reuse repeated frame index values")); -static cl::opt -ARMDynamicStackAlign("arm-dynamic-stack-alignment", cl::Hidden, cl::init(true), - cl::desc("Dynamically re-align the stack as needed")); - unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum, bool *isSPVFP) { if (isSPVFP) @@ -504,9 +500,6 @@ bool ARMBaseRegisterInfo:: needsStackRealignment(const MachineFunction &MF) const { - if (!ARMDynamicStackAlign) - return false; - const MachineFrameInfo *MFI = MF.getFrameInfo(); const ARMFunctionInfo *AFI = MF.getInfo(); unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); @@ -596,7 +589,7 @@ // Calculate and set max stack object alignment early, so we can decide // whether we will need stack realignment (and thus FP). - if (ARMDynamicStackAlign) { + if (RealignStack) { unsigned MaxAlign = std::max(MFI->getMaxAlignment(), calculateMaxStackAlignment(MFI)); MFI->setMaxAlignment(MaxAlign); From mrs at apple.com Mon Nov 9 17:12:38 2009 From: mrs at apple.com (Mike Stump) Date: Mon, 9 Nov 2009 15:12:38 -0800 Subject: [llvm-commits] [llvm] r86600 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp In-Reply-To: <6D81D7E0-1A25-4A71-99DE-685A7096A4A5@apple.com> References: <200911092228.nA9MSLFw002262@zion.cs.uiuc.edu> <6D81D7E0-1A25-4A71-99DE-685A7096A4A5@apple.com> Message-ID: On Nov 9, 2009, at 2:29 PM, Eric Christopher wrote: > On Nov 9, 2009, at 2:28 PM, Mike Stump wrote: >> Fix for 64-bit builds. > > Thanks. Guess that did work :) > > Please throw a testcase in somewhere to make sure I don't break it. Sure, checked in r86620. From nlewycky at google.com Mon Nov 9 17:17:27 2009 From: nlewycky at google.com (Nick Lewycky) Date: Mon, 9 Nov 2009 15:17:27 -0800 Subject: [llvm-commits] [llvm] r86613 - in /llvm/trunk: include/llvm/Analysis/InstructionSimplify.h lib/Analysis/CMakeLists.txt lib/Analysis/InstructionSimplify.cpp In-Reply-To: <200911092257.nA9MvxAt004112@zion.cs.uiuc.edu> References: <200911092257.nA9MvxAt004112@zion.cs.uiuc.edu> Message-ID: 2009/11/9 Chris Lattner > Author: lattner > Date: Mon Nov 9 16:57:59 2009 > New Revision: 86613 > > URL: http://llvm.org/viewvc/llvm-project?rev=86613&view=rev > Log: > stub out a new libanalysis "instruction simplify" interface that > takes decimated instructions and applies identities to them. This > is pretty minimal at this point, but I plan to pull some instcombine > logic out into these and similar routines. > > Added: > llvm/trunk/include/llvm/Analysis/InstructionSimplify.h > llvm/trunk/lib/Analysis/InstructionSimplify.cpp > Modified: > llvm/trunk/lib/Analysis/CMakeLists.txt > > Added: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionSimplify.h?rev=86613&view=auto > > > ============================================================================== > --- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h (added) > +++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Mon Nov 9 > 16:57:59 2009 > @@ -0,0 +1,37 @@ > +//===-- InstructionSimplify.h - Fold instructions into simpler forms > ------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > > +//===----------------------------------------------------------------------===// > +// > +// This file declares routines for folding instructions into simpler forms > that > +// do not require creating new instructions. For example, this does > constant > +// folding, and can handle identities like (X&0)->0. > +// > > +//===----------------------------------------------------------------------===// > + > +#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H > +#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H > + > +namespace llvm { > + class Value; > + class TargetData; > + > + /// SimplifyCompare - Given operands for a CmpInst, see if we can > + /// fold the result. If not, this returns null. > + Value *SimplifyCompare(unsigned Predicate, Value *LHS, Value *RHS, > + const TargetData *TD = 0); > + > + > + /// SimplifyBinOp - Given operands for a BinaryOperator, see if we can > + /// fold the result. If not, this returns null. > + Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, > + const TargetData *TD = 0); > + > +} // end namespace llvm > + > +#endif > + > > Modified: llvm/trunk/lib/Analysis/CMakeLists.txt > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=86613&r1=86612&r2=86613&view=diff > > > ============================================================================== > --- llvm/trunk/lib/Analysis/CMakeLists.txt (original) > +++ llvm/trunk/lib/Analysis/CMakeLists.txt Mon Nov 9 16:57:59 2009 > @@ -15,6 +15,7 @@ > IVUsers.cpp > InlineCost.cpp > InstCount.cpp > + InstructionSimplify.cpp > Interval.cpp > IntervalPartition.cpp > LibCallAliasAnalysis.cpp > > Added: llvm/trunk/lib/Analysis/InstructionSimplify.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=86613&view=auto > > > ============================================================================== > --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (added) > +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Mon Nov 9 16:57:59 > 2009 > @@ -0,0 +1,57 @@ > +//===- InstructionSimplify.cpp - Fold instruction operands > ----------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > > +//===----------------------------------------------------------------------===// > +// > +// This file implements routines for folding instructions into simpler > forms > +// that do not require creating new instructions. For example, this does > +// constant folding, and can handle identities like (X&0)->0. > +// > > +//===----------------------------------------------------------------------===// > + > +#include "llvm/Analysis/InstructionSimplify.h" > +#include "llvm/Analysis/ConstantFolding.h" > +#include "llvm/Instructions.h" > +using namespace llvm; > + > + > +/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can > +/// fold the result. If not, this returns null. > +Value *llvm::SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, > + const TargetData *TD) { > + if (Constant *CLHS = dyn_cast(LHS)) > + if (Constant *CRHS = dyn_cast(RHS)) { > + Constant *COps[] = {CLHS, CRHS}; > + return ConstantFoldInstOperands(Opcode, LHS->getType(), COps, 2, > TD); > + } > + return 0; > +} > + > + > +/// SimplifyCompare - Given operands for a CmpInst, see if we can > +/// fold the result. > +Value *llvm::SimplifyCompare(unsigned Predicate, Value *LHS, Value *RHS, > + const TargetData *TD) { > + CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate; > + > + if (Constant *CLHS = dyn_cast(LHS)) > + if (Constant *CRHS = dyn_cast(RHS)) { > + Constant *COps[] = {CLHS, CRHS}; > + return ConstantFoldCompareInstOperands(Pred, COps, 2, TD); > + } > + > + // If this is an integer compare and the LHS and RHS are the same, fold > it. > + if (LHS == RHS) > + if (isa(LHS->getType()) || > isa(LHS->getType())) { > + if (ICmpInst::isTrueWhenEqual(Pred)) > + return ConstantInt::getTrue(LHS->getContext()); > + else > + return ConstantInt::getFalse(LHS->getContext()); > + } > There's an CmpInst::isTrueWhenEqual and CmpInst::isFalseWhenEqual, both of which work on icmp and fcmp. Please use that instead, adding support for floats in the process! Nick > + return 0; > +} > + > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091109/48444335/attachment.html From sabre at nondot.org Mon Nov 9 17:28:39 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 09 Nov 2009 23:28:39 -0000 Subject: [llvm-commits] [llvm] r86624 - in /llvm/trunk: include/llvm/Analysis/InstructionSimplify.h include/llvm/InstrTypes.h lib/Analysis/InstructionSimplify.cpp lib/Transforms/Scalar/InstructionCombining.cpp lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200911092328.nA9NSeZs005269@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 17:28:39 2009 New Revision: 86624 URL: http://llvm.org/viewvc/llvm-project?rev=86624&view=rev Log: rename SimplifyCompare -> SimplifyCmpInst and split it into Simplify[IF]Cmp pieces. Add some predicates to CmpInst to determine whether a predicate is fp or int. Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h llvm/trunk/include/llvm/InstrTypes.h llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionSimplify.h?rev=86624&r1=86623&r2=86624&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h (original) +++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Mon Nov 9 17:28:39 2009 @@ -20,11 +20,24 @@ class Value; class TargetData; - /// SimplifyCompare - Given operands for a CmpInst, see if we can + /// SimplifyICmpInst - Given operands for an ICmpInst, see if we can /// fold the result. If not, this returns null. - Value *SimplifyCompare(unsigned Predicate, Value *LHS, Value *RHS, + Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, const TargetData *TD = 0); + /// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can + /// fold the result. If not, this returns null. + Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, + const TargetData *TD = 0); + + + //=== Helper functions for higher up the class hierarchy. + + + /// SimplifyCmpInst - Given operands for a CmpInst, see if we can + /// fold the result. If not, this returns null. + Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, + const TargetData *TD = 0); /// SimplifyBinOp - Given operands for a BinaryOperator, see if we can /// fold the result. If not, this returns null. Modified: llvm/trunk/include/llvm/InstrTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InstrTypes.h?rev=86624&r1=86623&r2=86624&view=diff ============================================================================== --- llvm/trunk/include/llvm/InstrTypes.h (original) +++ llvm/trunk/include/llvm/InstrTypes.h Mon Nov 9 17:28:39 2009 @@ -658,7 +658,7 @@ /// @brief Create a CmpInst static CmpInst *Create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2, const Twine &Name, BasicBlock *InsertAtEnd); - + /// @brief Get the opcode casted to the right type OtherOps getOpcode() const { return static_cast(Instruction::getOpcode()); @@ -670,6 +670,18 @@ /// @brief Set the predicate for this instruction to the specified value. void setPredicate(Predicate P) { SubclassData = P; } + static bool isFPPredicate(Predicate P) { + return P >= FIRST_FCMP_PREDICATE && P <= LAST_FCMP_PREDICATE; + } + + static bool isIntPredicate(Predicate P) { + return P >= FIRST_ICMP_PREDICATE && P <= LAST_ICMP_PREDICATE; + } + + bool isFPPredicate() const { return isFPPredicate(getPredicate()); } + bool isIntPredicate() const { return isIntPredicate(getPredicate()); } + + /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, /// OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc. /// @returns the inverse predicate for the instruction's current predicate. Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=86624&r1=86623&r2=86624&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Mon Nov 9 17:28:39 2009 @@ -32,11 +32,12 @@ } -/// SimplifyCompare - Given operands for a CmpInst, see if we can -/// fold the result. -Value *llvm::SimplifyCompare(unsigned Predicate, Value *LHS, Value *RHS, - const TargetData *TD) { +/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can +/// fold the result. If not, this returns null. +Value *llvm::SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, + const TargetData *TD) { CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate; + assert(CmpInst::isIntPredicate(Pred) && "Not an integer compare!"); if (Constant *CLHS = dyn_cast(LHS)) if (Constant *CRHS = dyn_cast(RHS)) @@ -44,12 +45,36 @@ // If this is an integer compare and the LHS and RHS are the same, fold it. if (LHS == RHS) - if (isa(LHS->getType()) || isa(LHS->getType())) { - if (ICmpInst::isTrueWhenEqual(Pred)) - return ConstantInt::getTrue(LHS->getContext()); - else - return ConstantInt::getFalse(LHS->getContext()); - } + if (ICmpInst::isTrueWhenEqual(Pred)) + return ConstantInt::getTrue(LHS->getContext()); + else + return ConstantInt::getFalse(LHS->getContext()); + + return 0; +} + +/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can +/// fold the result. If not, this returns null. +Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, + const TargetData *TD) { + CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate; + assert(CmpInst::isFPPredicate(Pred) && "Not an FP compare!"); + + if (Constant *CLHS = dyn_cast(LHS)) + if (Constant *CRHS = dyn_cast(RHS)) + return ConstantFoldCompareInstOperands(Pred, CLHS, CRHS, TD); + return 0; } + + +/// SimplifyCmpInst - Given operands for a CmpInst, see if we can +/// fold the result. +Value *llvm::SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, + const TargetData *TD) { + if (CmpInst::isIntPredicate((CmpInst::Predicate)Predicate)) + return SimplifyICmpInst(Predicate, LHS, RHS, TD); + return SimplifyFCmpInst(Predicate, LHS, RHS, TD); +} + Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=86624&r1=86623&r2=86624&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Nov 9 17:28:39 2009 @@ -42,6 +42,7 @@ #include "llvm/GlobalVariable.h" #include "llvm/Operator.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Target/TargetData.h" Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86624&r1=86623&r2=86624&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Mon Nov 9 17:28:39 2009 @@ -354,7 +354,7 @@ Value *LHS = PN->getIncomingValue(i); Value *RHS = Cmp->getOperand(1)->DoPHITranslation(BB, PredBB); - Value *Res = SimplifyCompare(Cmp->getPredicate(), LHS, RHS); + Value *Res = SimplifyCmpInst(Cmp->getPredicate(), LHS, RHS); if (Res == 0) continue; if (isa(Res)) From sabre at nondot.org Mon Nov 9 17:31:49 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 09 Nov 2009 23:31:49 -0000 Subject: [llvm-commits] [llvm] r86625 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200911092331.nA9NVn5c005428@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 17:31:49 2009 New Revision: 86625 URL: http://llvm.org/viewvc/llvm-project?rev=86625&view=rev Log: inline a simple function. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=86625&r1=86624&r2=86625&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Nov 9 17:31:49 2009 @@ -383,10 +383,6 @@ /// commutative operators. bool SimplifyCommutative(BinaryOperator &I); - /// SimplifyCompare - This reorders the operands of a CmpInst to get them in - /// most-complex to least-complex order. - bool SimplifyCompare(CmpInst &I); - /// SimplifyDemandedUseBits - Attempts to replace V with a simpler value /// based on the demanded bits. Value *SimplifyDemandedUseBits(Value *V, APInt DemandedMask, @@ -587,17 +583,6 @@ return Changed; } -/// SimplifyCompare - For a CmpInst this function just orders the operands -/// so that theyare listed from right (least complex) to left (most complex). -/// This puts constants before unary operators before binary operators. -bool InstCombiner::SimplifyCompare(CmpInst &I) { - if (getComplexity(I.getOperand(0)) >= getComplexity(I.getOperand(1))) - return false; - I.swapOperands(); - // Compare instructions are not associative so there's nothing else we can do. - return true; -} - // dyn_castNegVal - Given a 'sub' instruction, return the RHS of the instruction // if the LHS is a constant zero (which is the 'negate' form). // @@ -5945,7 +5930,16 @@ } Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) { - bool Changed = SimplifyCompare(I); + bool Changed = false; + + /// Orders the operands of the compare so that they are listed from most + /// complex to least complex. This puts constants before unary operators, + /// before binary operators. + if (getComplexity(I.getOperand(0)) < getComplexity(I.getOperand(1))) { + I.swapOperands(); + Changed = true; + } + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); // Fold trivial predicates. @@ -6050,7 +6044,16 @@ } Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { - bool Changed = SimplifyCompare(I); + bool Changed = false; + + /// Orders the operands of the compare so that they are listed from most + /// complex to least complex. This puts constants before unary operators, + /// before binary operators. + if (getComplexity(I.getOperand(0)) < getComplexity(I.getOperand(1))) { + I.swapOperands(); + Changed = true; + } + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); const Type *Ty = Op0->getType(); From gohman at apple.com Mon Nov 9 17:34:17 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 09 Nov 2009 23:34:17 -0000 Subject: [llvm-commits] [llvm] r86626 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200911092334.nA9NYHYj005520@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 17:34:17 2009 New Revision: 86626 URL: http://llvm.org/viewvc/llvm-project?rev=86626&view=rev Log: Pass the (optional) TargetData object to ConstantFoldInstOperands and ConstantFoldCompareInstOperands. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=86626&r1=86625&r2=86626&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Nov 9 17:34:17 2009 @@ -3811,7 +3811,8 @@ /// getConstantEvolvingPHI predicate, evaluate its value assuming the PHI node /// in the loop has the value PHIVal. If we can't fold this expression for some /// reason, return null. -static Constant *EvaluateExpression(Value *V, Constant *PHIVal) { +static Constant *EvaluateExpression(Value *V, Constant *PHIVal, + const TargetData *TD) { if (isa(V)) return PHIVal; if (Constant *C = dyn_cast(V)) return C; if (GlobalValue *GV = dyn_cast(V)) return GV; @@ -3821,15 +3822,15 @@ Operands.resize(I->getNumOperands()); for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { - Operands[i] = EvaluateExpression(I->getOperand(i), PHIVal); + Operands[i] = EvaluateExpression(I->getOperand(i), PHIVal, TD); if (Operands[i] == 0) return 0; } if (const CmpInst *CI = dyn_cast(I)) return ConstantFoldCompareInstOperands(CI->getPredicate(), Operands[0], - Operands[1]); + Operands[1], TD); return ConstantFoldInstOperands(I->getOpcode(), I->getType(), - &Operands[0], Operands.size()); + &Operands[0], Operands.size(), TD); } /// getConstantEvolutionLoopExitValue - If we know that the specified Phi is @@ -3875,7 +3876,7 @@ return RetVal = PHIVal; // Got exit value! // Compute the value of the PHI node for the next iteration. - Constant *NextPHI = EvaluateExpression(BEValue, PHIVal); + Constant *NextPHI = EvaluateExpression(BEValue, PHIVal, TD); if (NextPHI == PHIVal) return RetVal = NextPHI; // Stopped evolving! if (NextPHI == 0) @@ -3916,7 +3917,7 @@ for (Constant *PHIVal = StartCST; IterationNum != MaxIterations; ++IterationNum) { ConstantInt *CondVal = - dyn_cast_or_null(EvaluateExpression(Cond, PHIVal)); + dyn_cast_or_null(EvaluateExpression(Cond, PHIVal, TD)); // Couldn't symbolically evaluate. if (!CondVal) return getCouldNotCompute(); @@ -3927,7 +3928,7 @@ } // Compute the value of the PHI node for the next iteration. - Constant *NextPHI = EvaluateExpression(BEValue, PHIVal); + Constant *NextPHI = EvaluateExpression(BEValue, PHIVal, TD); if (NextPHI == 0 || NextPHI == PHIVal) return getCouldNotCompute();// Couldn't evaluate or not making progress... PHIVal = NextPHI; @@ -4036,10 +4037,10 @@ Constant *C; if (const CmpInst *CI = dyn_cast(I)) C = ConstantFoldCompareInstOperands(CI->getPredicate(), - Operands[0], Operands[1]); + Operands[0], Operands[1], TD); else C = ConstantFoldInstOperands(I->getOpcode(), I->getType(), - &Operands[0], Operands.size()); + &Operands[0], Operands.size(), TD); return getSCEV(C); } } From mrs at apple.com Mon Nov 9 17:48:01 2009 From: mrs at apple.com (Mike Stump) Date: Mon, 9 Nov 2009 15:48:01 -0800 Subject: [llvm-commits] [llvm] r86547 - in /llvm/trunk: cmake/config-ix.cmake include/llvm/Config/config.h.cmake In-Reply-To: <200911091526.nA9FQhRr016776@zion.cs.uiuc.edu> References: <200911091526.nA9FQhRr016776@zion.cs.uiuc.edu> Message-ID: <05076F8D-8E99-4BCD-BDA0-AB1F2FD5DA05@apple.com> On Nov 9, 2009, at 7:26 AM, Oscar Fuentes wrote: > Author: ofv > Date: Mon Nov 9 09:26:40 2009 > New Revision: 86547 > > URL: http://llvm.org/viewvc/llvm-project?rev=86547&view=rev > Log: > CMake: Detect gv, circo, twopi, neato, fdo, dot and dotty. > + unset(LLVM_PATH_${NAME} CACHE) I get: -- Performing Test HAVE_U_INT64_T - Success CMake Error at cmake/config-ix.cmake:139 (unset): Unknown CMake command "unset". Call Stack (most recent call first): cmake/config-ix.cmake:143 (llvm_find_program) CMakeLists.txt:161 (include) -- Configuring incomplete, errors occurred! ? I'm using cmake version 2.6-patch 2. From sabre at nondot.org Mon Nov 9 17:55:12 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 09 Nov 2009 23:55:12 -0000 Subject: [llvm-commits] [llvm] r86627 - in /llvm/trunk/lib: Analysis/InstructionSimplify.cpp Transforms/Scalar/InstructionCombining.cpp Message-ID: <200911092355.nA9NtCrp006300@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 17:55:12 2009 New Revision: 86627 URL: http://llvm.org/viewvc/llvm-project?rev=86627&view=rev Log: pull a bunch of logic out of instcombine into instsimplify for compare simplification, this handles the foldable fcmp x,x cases among many others. Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=86627&r1=86626&r2=86627&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Mon Nov 9 17:55:12 2009 @@ -31,6 +31,10 @@ return 0; } +static const Type *GetCompareTy(Value *Op) { + return CmpInst::makeCmpResultType(Op->getType()); +} + /// SimplifyICmpInst - Given operands for an ICmpInst, see if we can /// fold the result. If not, this returns null. @@ -43,13 +47,59 @@ if (Constant *CRHS = dyn_cast(RHS)) return ConstantFoldCompareInstOperands(Pred, CLHS, CRHS, TD); - // If this is an integer compare and the LHS and RHS are the same, fold it. + // ITy - This is the return type of the compare we're considering. + const Type *ITy = GetCompareTy(LHS); + + // icmp X, X -> true/false if (LHS == RHS) - if (ICmpInst::isTrueWhenEqual(Pred)) - return ConstantInt::getTrue(LHS->getContext()); - else - return ConstantInt::getFalse(LHS->getContext()); + return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred)); + // If we have a constant, make sure it is on the RHS. + if (isa(LHS)) { + std::swap(LHS, RHS); + Pred = CmpInst::getSwappedPredicate(Pred); + } + + if (isa(RHS)) // X icmp undef -> undef + return UndefValue::get(ITy); + + // icmp , - Global/Stack value + // addresses never equal each other! We already know that Op0 != Op1. + if ((isa(LHS) || isa(LHS) || + isa(LHS)) && + (isa(RHS) || isa(RHS) || + isa(RHS))) + return ConstantInt::get(ITy, CmpInst::isFalseWhenEqual(Pred)); + + // See if we are doing a comparison with a constant. + if (ConstantInt *CI = dyn_cast(RHS)) { + // If we have an icmp le or icmp ge instruction, turn it into the + // appropriate icmp lt or icmp gt instruction. This allows us to rely on + // them being folded in the code below. + switch (Pred) { + default: break; + case ICmpInst::ICMP_ULE: + if (CI->isMaxValue(false)) // A <=u MAX -> TRUE + return ConstantInt::getTrue(CI->getContext()); + break; + case ICmpInst::ICMP_SLE: + if (CI->isMaxValue(true)) // A <=s MAX -> TRUE + return ConstantInt::getTrue(CI->getContext()); + break; + case ICmpInst::ICMP_UGE: + if (CI->isMinValue(false)) // A >=u MIN -> TRUE + return ConstantInt::getTrue(CI->getContext()); + break; + case ICmpInst::ICMP_SGE: + if (CI->isMinValue(true)) // A >=s MIN -> TRUE + return ConstantInt::getTrue(CI->getContext()); + break; + } + + + } + + return 0; } @@ -64,6 +114,44 @@ if (Constant *CRHS = dyn_cast(RHS)) return ConstantFoldCompareInstOperands(Pred, CLHS, CRHS, TD); + // Fold trivial predicates. + if (Pred == FCmpInst::FCMP_FALSE) + return ConstantInt::get(GetCompareTy(LHS), 0); + if (Pred == FCmpInst::FCMP_TRUE) + return ConstantInt::get(GetCompareTy(LHS), 1); + + // If we have a constant, make sure it is on the RHS. + if (isa(LHS)) { + std::swap(LHS, RHS); + Pred = CmpInst::getSwappedPredicate(Pred); + } + + if (isa(RHS)) // fcmp pred X, undef -> undef + return UndefValue::get(GetCompareTy(LHS)); + + // fcmp x,x -> true/false. Not all compares are foldable. + if (LHS == RHS) { + if (CmpInst::isTrueWhenEqual(Pred)) + return ConstantInt::get(GetCompareTy(LHS), 1); + if (CmpInst::isFalseWhenEqual(Pred)) + return ConstantInt::get(GetCompareTy(LHS), 0); + } + + // Handle fcmp with constant RHS + if (Constant *RHSC = dyn_cast(RHS)) { + // If the constant is a nan, see if we can fold the comparison based on it. + if (ConstantFP *CFP = dyn_cast(RHSC)) { + if (CFP->getValueAPF().isNaN()) { + if (FCmpInst::isOrdered(Pred)) // True "if ordered and foo" + return ConstantInt::getFalse(CFP->getContext()); + assert(FCmpInst::isUnordered(Pred) && + "Comparison must be either ordered or unordered!"); + // True if unordered. + return ConstantInt::getTrue(CFP->getContext()); + } + } + } + return 0; } Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=86627&r1=86626&r2=86627&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Nov 9 17:55:12 2009 @@ -5941,26 +5941,14 @@ } Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - - // Fold trivial predicates. - if (I.getPredicate() == FCmpInst::FCMP_FALSE) - return ReplaceInstUsesWith(I, ConstantInt::get(I.getType(), 0)); - if (I.getPredicate() == FCmpInst::FCMP_TRUE) - return ReplaceInstUsesWith(I, ConstantInt::get(I.getType(), 1)); + if (Value *V = SimplifyFCmpInst(I.getPredicate(), Op0, Op1, TD)) + return ReplaceInstUsesWith(I, V); + // Simplify 'fcmp pred X, X' if (Op0 == Op1) { switch (I.getPredicate()) { default: llvm_unreachable("Unknown predicate!"); - case FCmpInst::FCMP_UEQ: // True if unordered or equal - case FCmpInst::FCMP_UGE: // True if unordered, greater than, or equal - case FCmpInst::FCMP_ULE: // True if unordered, less than, or equal - return ReplaceInstUsesWith(I, ConstantInt::get(I.getType(), 1)); - case FCmpInst::FCMP_OGT: // True if ordered and greater than - case FCmpInst::FCMP_OLT: // True if ordered and less than - case FCmpInst::FCMP_ONE: // True if ordered and operands are unequal - return ReplaceInstUsesWith(I, ConstantInt::get(I.getType(), 0)); - case FCmpInst::FCMP_UNO: // True if unordered: isnan(X) | isnan(Y) case FCmpInst::FCMP_ULT: // True if unordered or less than case FCmpInst::FCMP_UGT: // True if unordered or greater than @@ -5981,23 +5969,8 @@ } } - if (isa(Op1)) // fcmp pred X, undef -> undef - return ReplaceInstUsesWith(I, UndefValue::get(I.getType())); - // Handle fcmp with constant RHS if (Constant *RHSC = dyn_cast(Op1)) { - // If the constant is a nan, see if we can fold the comparison based on it. - if (ConstantFP *CFP = dyn_cast(RHSC)) { - if (CFP->getValueAPF().isNaN()) { - if (FCmpInst::isOrdered(I.getPredicate())) // True if ordered and... - return ReplaceInstUsesWith(I, ConstantInt::getFalse(*Context)); - assert(FCmpInst::isUnordered(I.getPredicate()) && - "Comparison must be either ordered or unordered!"); - // True if unordered. - return ReplaceInstUsesWith(I, ConstantInt::getTrue(*Context)); - } - } - if (Instruction *LHSI = dyn_cast(Op0)) switch (LHSI->getOpcode()) { case Instruction::PHI: @@ -6055,25 +6028,12 @@ } Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); + + if (Value *V = SimplifyICmpInst(I.getPredicate(), Op0, Op1, TD)) + return ReplaceInstUsesWith(I, V); + const Type *Ty = Op0->getType(); - // icmp X, X - if (Op0 == Op1) - return ReplaceInstUsesWith(I, ConstantInt::get(I.getType(), - I.isTrueWhenEqual())); - - if (isa(Op1)) // X icmp undef -> undef - return ReplaceInstUsesWith(I, UndefValue::get(I.getType())); - - // icmp , - Global/Stack value - // addresses never equal each other! We already know that Op0 != Op1. - if ((isa(Op0) || isa(Op0) || - isa(Op0)) && - (isa(Op1) || isa(Op1) || - isa(Op1))) - return ReplaceInstUsesWith(I, ConstantInt::get(Type::getInt1Ty(*Context), - !I.isTrueWhenEqual())); - // icmp's with boolean values can always be turned into bitwise operations if (Ty == Type::getInt1Ty(*Context)) { switch (I.getPredicate()) { @@ -6137,27 +6097,24 @@ // If we have an icmp le or icmp ge instruction, turn it into the // appropriate icmp lt or icmp gt instruction. This allows us to rely on - // them being folded in the code below. + // them being folded in the code below. The SimplifyICmpInst code has + // already handled the edge cases for us, so we just assert on them. switch (I.getPredicate()) { default: break; case ICmpInst::ICMP_ULE: - if (CI->isMaxValue(false)) // A <=u MAX -> TRUE - return ReplaceInstUsesWith(I, ConstantInt::getTrue(*Context)); + assert(!CI->isMaxValue(false)); // A <=u MAX -> TRUE return new ICmpInst(ICmpInst::ICMP_ULT, Op0, AddOne(CI)); case ICmpInst::ICMP_SLE: - if (CI->isMaxValue(true)) // A <=s MAX -> TRUE - return ReplaceInstUsesWith(I, ConstantInt::getTrue(*Context)); + assert(!CI->isMaxValue(true)); // A <=s MAX -> TRUE return new ICmpInst(ICmpInst::ICMP_SLT, Op0, AddOne(CI)); case ICmpInst::ICMP_UGE: - if (CI->isMinValue(false)) // A >=u MIN -> TRUE - return ReplaceInstUsesWith(I, ConstantInt::getTrue(*Context)); + assert(!CI->isMinValue(false)); // A >=u MIN -> TRUE return new ICmpInst(ICmpInst::ICMP_UGT, Op0, SubOne(CI)); case ICmpInst::ICMP_SGE: - if (CI->isMinValue(true)) // A >=s MIN -> TRUE - return ReplaceInstUsesWith(I, ConstantInt::getTrue(*Context)); + assert(!CI->isMinValue(true)); // A >=s MIN -> TRUE return new ICmpInst(ICmpInst::ICMP_SGT, Op0, SubOne(CI)); } From david_goodwin at apple.com Mon Nov 9 18:15:47 2009 From: david_goodwin at apple.com (David Goodwin) Date: Tue, 10 Nov 2009 00:15:47 -0000 Subject: [llvm-commits] [llvm] r86628 - in /llvm/trunk: include/llvm/Target/TargetSubtarget.h lib/CodeGen/AggressiveAntiDepBreaker.cpp lib/CodeGen/AggressiveAntiDepBreaker.h lib/CodeGen/PostRASchedulerList.cpp lib/Target/ARM/ARMSubtarget.h lib/Target/X86/X86Subtarget.h Message-ID: <200911100015.nAA0FmdV007190@zion.cs.uiuc.edu> Author: david_goodwin Date: Mon Nov 9 18:15:47 2009 New Revision: 86628 URL: http://llvm.org/viewvc/llvm-project?rev=86628&view=rev Log: Allow targets to specify register classes whose member registers should not be renamed to break anti-dependencies. Modified: llvm/trunk/include/llvm/Target/TargetSubtarget.h llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp llvm/trunk/lib/Target/ARM/ARMSubtarget.h llvm/trunk/lib/Target/X86/X86Subtarget.h Modified: llvm/trunk/include/llvm/Target/TargetSubtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSubtarget.h?rev=86628&r1=86627&r2=86628&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetSubtarget.h (original) +++ llvm/trunk/include/llvm/Target/TargetSubtarget.h Mon Nov 9 18:15:47 2009 @@ -15,6 +15,8 @@ #define LLVM_TARGET_TARGETSUBTARGET_H #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/ADT/SmallVector.h" namespace llvm { @@ -36,6 +38,7 @@ // AntiDepBreakMode - Type of anti-dependence breaking that should // be performed before post-RA scheduling. typedef enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL } AntiDepBreakMode; + typedef SmallVector ExcludedRCVector; virtual ~TargetSubtarget(); @@ -49,8 +52,10 @@ // scheduling and the specified optimization level meets the requirement // return true to enable post-register-allocation scheduling. virtual bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, - AntiDepBreakMode& mode) const { - mode = ANTIDEP_NONE; + AntiDepBreakMode& Mode, + ExcludedRCVector& ExcludedRCs) const { + Mode = ANTIDEP_NONE; + ExcludedRCs.clear(); return false; } Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp?rev=86628&r1=86627&r2=86628&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp (original) +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp Mon Nov 9 18:15:47 2009 @@ -99,12 +99,24 @@ AggressiveAntiDepBreaker:: -AggressiveAntiDepBreaker(MachineFunction& MFi) : +AggressiveAntiDepBreaker(MachineFunction& MFi, + TargetSubtarget::ExcludedRCVector& ExcludedRCs) : AntiDepBreaker(), MF(MFi), MRI(MF.getRegInfo()), TRI(MF.getTarget().getRegisterInfo()), AllocatableSet(TRI->getAllocatableSet(MF)), State(NULL), SavedState(NULL) { + /* Remove all registers from excluded RCs from the allocatable + register set. */ + for (unsigned i = 0, e = ExcludedRCs.size(); i < e; ++i) { + BitVector NotRenameable = TRI->getAllocatableSet(MF, ExcludedRCs[i]).flip(); + AllocatableSet &= NotRenameable; + } + + DEBUG(errs() << "AntiDep Renameable Registers:"); + DEBUG(for (int r = AllocatableSet.find_first(); r != -1; + r = AllocatableSet.find_next(r)) + errs() << " " << TRI->getName(r)); } AggressiveAntiDepBreaker::~AggressiveAntiDepBreaker() { Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h?rev=86628&r1=86627&r2=86628&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h (original) +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h Mon Nov 9 18:15:47 2009 @@ -23,6 +23,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/Target/TargetSubtarget.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/SmallSet.h" @@ -112,7 +113,7 @@ /// AllocatableSet - The set of allocatable registers. /// We'll be ignoring anti-dependencies on non-allocatable registers, /// because they may not be safe to break. - const BitVector AllocatableSet; + BitVector AllocatableSet; /// State - The state used to identify and rename anti-dependence /// registers. @@ -124,7 +125,8 @@ AggressiveAntiDepState *SavedState; public: - AggressiveAntiDepBreaker(MachineFunction& MFi); + AggressiveAntiDepBreaker(MachineFunction& MFi, + TargetSubtarget::ExcludedRCVector& ExcludedRCs); ~AggressiveAntiDepBreaker(); /// GetMaxTrials - As anti-dependencies are broken, additional Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=86628&r1=86627&r2=86628&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Nov 9 18:15:47 2009 @@ -216,13 +216,14 @@ // Check for explicit enable/disable of post-ra scheduling. TargetSubtarget::AntiDepBreakMode AntiDepMode = TargetSubtarget::ANTIDEP_NONE; + TargetSubtarget::ExcludedRCVector ExcludedRCs; if (EnablePostRAScheduler.getPosition() > 0) { if (!EnablePostRAScheduler) return false; } else { // Check that post-RA scheduling is enabled for this target. const TargetSubtarget &ST = Fn.getTarget().getSubtarget(); - if (!ST.enablePostRAScheduler(OptLevel, AntiDepMode)) + if (!ST.enablePostRAScheduler(OptLevel, AntiDepMode, ExcludedRCs)) return false; } @@ -243,7 +244,7 @@ (ScheduleHazardRecognizer *)new SimpleHazardRecognizer(); AntiDepBreaker *ADB = ((AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? - (AntiDepBreaker *)new AggressiveAntiDepBreaker(Fn) : + (AntiDepBreaker *)new AggressiveAntiDepBreaker(Fn, ExcludedRCs) : ((AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? (AntiDepBreaker *)new CriticalAntiDepBreaker(Fn) : NULL)); Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=86628&r1=86627&r2=86628&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Mon Nov 9 18:15:47 2009 @@ -17,6 +17,7 @@ #include "llvm/Target/TargetInstrItineraries.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetSubtarget.h" +#include "ARMBaseRegisterInfo.h" #include namespace llvm { @@ -129,8 +130,11 @@ /// enablePostRAScheduler - True at 'More' optimization except /// for Thumb1. bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, - TargetSubtarget::AntiDepBreakMode& mode) const { - mode = TargetSubtarget::ANTIDEP_CRITICAL; + TargetSubtarget::AntiDepBreakMode& Mode, + ExcludedRCVector& ExcludedRCs) const { + Mode = TargetSubtarget::ANTIDEP_CRITICAL; + ExcludedRCs.clear(); + ExcludedRCs.push_back(&ARM::GPRRegClass); return PostRAScheduler && OptLevel >= CodeGenOpt::Default; } Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=86628&r1=86627&r2=86628&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.h (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.h Mon Nov 9 18:15:47 2009 @@ -219,8 +219,10 @@ /// enablePostRAScheduler - X86 target is enabling post-alloc scheduling /// at 'More' optimization level. bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, - TargetSubtarget::AntiDepBreakMode& mode) const { - mode = TargetSubtarget::ANTIDEP_CRITICAL; + TargetSubtarget::AntiDepBreakMode& Mode, + ExcludedRCVector& ExcludedRCs) const { + Mode = TargetSubtarget::ANTIDEP_CRITICAL; + ExcludedRCs.clear(); return OptLevel >= CodeGenOpt::Default; } }; From clattner at apple.com Mon Nov 9 18:25:33 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 9 Nov 2009 16:25:33 -0800 Subject: [llvm-commits] [llvm] r86628 - in /llvm/trunk: include/llvm/Target/TargetSubtarget.h lib/CodeGen/AggressiveAntiDepBreaker.cpp lib/CodeGen/AggressiveAntiDepBreaker.h lib/CodeGen/PostRASchedulerList.cpp lib/Target/ARM/ARMSubtarget.h lib/Target/X86/X86Subtarget.h In-Reply-To: <200911100015.nAA0FmdV007190@zion.cs.uiuc.edu> References: <200911100015.nAA0FmdV007190@zion.cs.uiuc.edu> Message-ID: On Nov 9, 2009, at 4:15 PM, David Goodwin wrote: > Author: david_goodwin > Date: Mon Nov 9 18:15:47 2009 > New Revision: 86628 > > URL: http://llvm.org/viewvc/llvm-project?rev=86628&view=rev > Log: > Allow targets to specify register classes whose member registers > should not be renamed to break anti-dependencies. I don't have anything to say about the technical merits of this patch, but... > +++ llvm/trunk/include/llvm/Target/TargetSubtarget.h Mon Nov 9 > 18:15:47 2009 > @@ -15,6 +15,8 @@ > #define LLVM_TARGET_TARGETSUBTARGET_H > > #include "llvm/Target/TargetMachine.h" > +#include "llvm/Target/TargetRegisterInfo.h" > +#include "llvm/ADT/SmallVector.h" Please just forward declare what you need from these two headers instead of #including them. Also, for APIs that take a smallvector and fill it in, they should generally take a SmallVectorImpl instead of specifying a size (that way the client has the ability to pick a size). You can forward declare SmallVectorImpl like this: namespace llvm { template class SmallVectorImpl; } and move the virtual method out of line to avoid the .clear() in the header. Thanks David, -Chris > > namespace llvm { > > @@ -36,6 +38,7 @@ > // AntiDepBreakMode - Type of anti-dependence breaking that should > // be performed before post-RA scheduling. > typedef enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL } > AntiDepBreakMode; > + typedef SmallVector ExcludedRCVector; > > virtual ~TargetSubtarget(); > > @@ -49,8 +52,10 @@ > // scheduling and the specified optimization level meets the > requirement > // return true to enable post-register-allocation scheduling. > virtual bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, > - AntiDepBreakMode& mode) const { > - mode = ANTIDEP_NONE; > + AntiDepBreakMode& Mode, > + ExcludedRCVector& ExcludedRCs) > const { > + Mode = ANTIDEP_NONE; > + ExcludedRCs.clear(); > return false; > } > > > Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp?rev=86628&r1=86627&r2=86628&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp (original) > +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp Mon Nov 9 > 18:15:47 2009 > @@ -99,12 +99,24 @@ > > > AggressiveAntiDepBreaker:: > -AggressiveAntiDepBreaker(MachineFunction& MFi) : > +AggressiveAntiDepBreaker(MachineFunction& MFi, > + TargetSubtarget::ExcludedRCVector& > ExcludedRCs) : > AntiDepBreaker(), MF(MFi), > MRI(MF.getRegInfo()), > TRI(MF.getTarget().getRegisterInfo()), > AllocatableSet(TRI->getAllocatableSet(MF)), > State(NULL), SavedState(NULL) { > + /* Remove all registers from excluded RCs from the allocatable > + register set. */ > + for (unsigned i = 0, e = ExcludedRCs.size(); i < e; ++i) { > + BitVector NotRenameable = TRI->getAllocatableSet(MF, > ExcludedRCs[i]).flip(); > + AllocatableSet &= NotRenameable; > + } > + > + DEBUG(errs() << "AntiDep Renameable Registers:"); > + DEBUG(for (int r = AllocatableSet.find_first(); r != -1; > + r = AllocatableSet.find_next(r)) > + errs() << " " << TRI->getName(r)); > } > > AggressiveAntiDepBreaker::~AggressiveAntiDepBreaker() { > > Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h?rev=86628&r1=86627&r2=86628&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h (original) > +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h Mon Nov 9 > 18:15:47 2009 > @@ -23,6 +23,7 @@ > #include "llvm/CodeGen/MachineFunction.h" > #include "llvm/CodeGen/MachineRegisterInfo.h" > #include "llvm/CodeGen/ScheduleDAG.h" > +#include "llvm/Target/TargetSubtarget.h" > #include "llvm/Target/TargetRegisterInfo.h" > #include "llvm/ADT/BitVector.h" > #include "llvm/ADT/SmallSet.h" > @@ -112,7 +113,7 @@ > /// AllocatableSet - The set of allocatable registers. > /// We'll be ignoring anti-dependencies on non-allocatable > registers, > /// because they may not be safe to break. > - const BitVector AllocatableSet; > + BitVector AllocatableSet; > > /// State - The state used to identify and rename anti-dependence > /// registers. > @@ -124,7 +125,8 @@ > AggressiveAntiDepState *SavedState; > > public: > - AggressiveAntiDepBreaker(MachineFunction& MFi); > + AggressiveAntiDepBreaker(MachineFunction& MFi, > + TargetSubtarget::ExcludedRCVector& > ExcludedRCs); > ~AggressiveAntiDepBreaker(); > > /// GetMaxTrials - As anti-dependencies are broken, additional > > Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=86628&r1=86627&r2=86628&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) > +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Nov 9 > 18:15:47 2009 > @@ -216,13 +216,14 @@ > > // Check for explicit enable/disable of post-ra scheduling. > TargetSubtarget::AntiDepBreakMode AntiDepMode = > TargetSubtarget::ANTIDEP_NONE; > + TargetSubtarget::ExcludedRCVector ExcludedRCs; > if (EnablePostRAScheduler.getPosition() > 0) { > if (!EnablePostRAScheduler) > return false; > } else { > // Check that post-RA scheduling is enabled for this target. > const TargetSubtarget &ST = > Fn.getTarget().getSubtarget(); > - if (!ST.enablePostRAScheduler(OptLevel, AntiDepMode)) > + if (!ST.enablePostRAScheduler(OptLevel, AntiDepMode, > ExcludedRCs)) > return false; > } > > @@ -243,7 +244,7 @@ > (ScheduleHazardRecognizer *)new SimpleHazardRecognizer(); > AntiDepBreaker *ADB = > ((AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? > - (AntiDepBreaker *)new AggressiveAntiDepBreaker(Fn) : > + (AntiDepBreaker *)new AggressiveAntiDepBreaker(Fn, > ExcludedRCs) : > ((AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? > (AntiDepBreaker *)new CriticalAntiDepBreaker(Fn) : NULL)); > > > Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=86628&r1=86627&r2=86628&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Mon Nov 9 18:15:47 2009 > @@ -17,6 +17,7 @@ > #include "llvm/Target/TargetInstrItineraries.h" > #include "llvm/Target/TargetMachine.h" > #include "llvm/Target/TargetSubtarget.h" > +#include "ARMBaseRegisterInfo.h" > #include > > namespace llvm { > @@ -129,8 +130,11 @@ > /// enablePostRAScheduler - True at 'More' optimization except > /// for Thumb1. > bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, > - TargetSubtarget::AntiDepBreakMode& > mode) const { > - mode = TargetSubtarget::ANTIDEP_CRITICAL; > + TargetSubtarget::AntiDepBreakMode& Mode, > + ExcludedRCVector& ExcludedRCs) const { > + Mode = TargetSubtarget::ANTIDEP_CRITICAL; > + ExcludedRCs.clear(); > + ExcludedRCs.push_back(&ARM::GPRRegClass); > return PostRAScheduler && OptLevel >= CodeGenOpt::Default; > } > > > Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=86628&r1=86627&r2=86628&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86Subtarget.h (original) > +++ llvm/trunk/lib/Target/X86/X86Subtarget.h Mon Nov 9 18:15:47 2009 > @@ -219,8 +219,10 @@ > /// enablePostRAScheduler - X86 target is enabling post-alloc > scheduling > /// at 'More' optimization level. > bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, > - TargetSubtarget::AntiDepBreakMode& > mode) const { > - mode = TargetSubtarget::ANTIDEP_CRITICAL; > + TargetSubtarget::AntiDepBreakMode& Mode, > + ExcludedRCVector& ExcludedRCs) const { > + Mode = TargetSubtarget::ANTIDEP_CRITICAL; > + ExcludedRCs.clear(); > return OptLevel >= CodeGenOpt::Default; > } > }; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From daniel at zuster.org Mon Nov 9 18:43:59 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 10 Nov 2009 00:43:59 -0000 Subject: [llvm-commits] [llvm] r86630 - in /llvm/trunk: include/llvm/Support/MemoryBuffer.h lib/Linker/LinkItems.cpp lib/Support/MemoryBuffer.cpp lib/VMCore/Core.cpp Message-ID: <200911100043.nAA0hxqW008252@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Nov 9 18:43:58 2009 New Revision: 86630 URL: http://llvm.org/viewvc/llvm-project?rev=86630&view=rev Log: Fix MemoryBuffer::getSTDIN to *not* return null if stdin is empty, this is a lame API. Also, Stringrefify some more MemoryBuffer functions, and add two performance FIXMEs. Modified: llvm/trunk/include/llvm/Support/MemoryBuffer.h llvm/trunk/lib/Linker/LinkItems.cpp llvm/trunk/lib/Support/MemoryBuffer.cpp llvm/trunk/lib/VMCore/Core.cpp Modified: llvm/trunk/include/llvm/Support/MemoryBuffer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MemoryBuffer.h?rev=86630&r1=86629&r2=86630&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/MemoryBuffer.h (original) +++ llvm/trunk/include/llvm/Support/MemoryBuffer.h Mon Nov 9 18:43:58 2009 @@ -57,7 +57,7 @@ /// MemoryBuffer if successful, otherwise returning null. If FileSize is /// specified, this means that the client knows that the file exists and that /// it has the specified size. - static MemoryBuffer *getFile(const char *Filename, + static MemoryBuffer *getFile(StringRef Filename, std::string *ErrStr = 0, int64_t FileSize = -1); @@ -84,29 +84,18 @@ /// memory allocated by this method. The memory is owned by the MemoryBuffer /// object. static MemoryBuffer *getNewUninitMemBuffer(size_t Size, - const char *BufferName = ""); + StringRef BufferName = ""); - /// getSTDIN - Read all of stdin into a file buffer, and return it. This - /// returns null if stdin is empty. + /// getSTDIN - Read all of stdin into a file buffer, and return it. static MemoryBuffer *getSTDIN(); /// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin /// if the Filename is "-". If an error occurs, this returns null and fills - /// in *ErrStr with a reason. If stdin is empty, this API (unlike getSTDIN) - /// returns an empty buffer. - static MemoryBuffer *getFileOrSTDIN(const char *Filename, - std::string *ErrStr = 0, - int64_t FileSize = -1); - - /// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin - /// if the Filename is "-". If an error occurs, this returns null and fills /// in *ErrStr with a reason. - static MemoryBuffer *getFileOrSTDIN(const std::string &FN, + static MemoryBuffer *getFileOrSTDIN(StringRef Filename, std::string *ErrStr = 0, - int64_t FileSize = -1) { - return getFileOrSTDIN(FN.c_str(), ErrStr, FileSize); - } + int64_t FileSize = -1); }; } // end namespace llvm Modified: llvm/trunk/lib/Linker/LinkItems.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkItems.cpp?rev=86630&r1=86629&r2=86630&view=diff ============================================================================== --- llvm/trunk/lib/Linker/LinkItems.cpp (original) +++ llvm/trunk/lib/Linker/LinkItems.cpp Mon Nov 9 18:43:58 2009 @@ -160,14 +160,17 @@ // Check for a file of name "-", which means "read standard input" if (File.str() == "-") { std::auto_ptr M; - if (MemoryBuffer *Buffer = MemoryBuffer::getSTDIN()) { + MemoryBuffer *Buffer = MemoryBuffer::getSTDIN(); + if (!Buffer->getBufferSize()) { + delete Buffer; + Error = "standard input is empty"; + } else { M.reset(ParseBitcodeFile(Buffer, Context, &Error)); delete Buffer; if (M.get()) if (!LinkInModule(M.get(), &Error)) return false; - } else - Error = "standard input is empty"; + } return error("Cannot link stdin: " + Error); } Modified: llvm/trunk/lib/Support/MemoryBuffer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/MemoryBuffer.cpp?rev=86630&r1=86629&r2=86630&view=diff ============================================================================== --- llvm/trunk/lib/Support/MemoryBuffer.cpp (original) +++ llvm/trunk/lib/Support/MemoryBuffer.cpp Mon Nov 9 18:43:58 2009 @@ -70,7 +70,7 @@ class MemoryBufferMem : public MemoryBuffer { std::string FileID; public: - MemoryBufferMem(const char *Start, const char *End, const char *FID, + MemoryBufferMem(const char *Start, const char *End, StringRef FID, bool Copy = false) : FileID(FID) { if (!Copy) @@ -107,7 +107,7 @@ /// initialize the memory allocated by this method. The memory is owned by /// the MemoryBuffer object. MemoryBuffer *MemoryBuffer::getNewUninitMemBuffer(size_t Size, - const char *BufferName) { + StringRef BufferName) { char *Buf = (char *)malloc((Size+1) * sizeof(char)); if (!Buf) return 0; Buf[Size] = 0; @@ -134,17 +134,12 @@ /// if the Filename is "-". If an error occurs, this returns null and fills /// in *ErrStr with a reason. If stdin is empty, this API (unlike getSTDIN) /// returns an empty buffer. -MemoryBuffer *MemoryBuffer::getFileOrSTDIN(const char *Filename, +MemoryBuffer *MemoryBuffer::getFileOrSTDIN(StringRef Filename, std::string *ErrStr, int64_t FileSize) { - if (Filename[0] != '-' || Filename[1] != 0) - return getFile(Filename, ErrStr, FileSize); - MemoryBuffer *M = getSTDIN(); - if (M) return M; - - // If stdin was empty, M is null. Cons up an empty memory buffer now. - const char *EmptyStr = ""; - return MemoryBuffer::getMemBuffer(EmptyStr, EmptyStr, ""); + if (Filename == "-") + return getSTDIN(); + return getFile(Filename, ErrStr, FileSize); } //===----------------------------------------------------------------------===// @@ -158,7 +153,7 @@ class MemoryBufferMMapFile : public MemoryBuffer { std::string Filename; public: - MemoryBufferMMapFile(const char *filename, const char *Pages, uint64_t Size) + MemoryBufferMMapFile(StringRef filename, const char *Pages, uint64_t Size) : Filename(filename) { init(Pages, Pages+Size); } @@ -173,13 +168,13 @@ }; } -MemoryBuffer *MemoryBuffer::getFile(const char *Filename, std::string *ErrStr, +MemoryBuffer *MemoryBuffer::getFile(StringRef Filename, std::string *ErrStr, int64_t FileSize) { int OpenFlags = 0; #ifdef O_BINARY OpenFlags |= O_BINARY; // Open input file in binary mode on win32. #endif - int FD = ::open(Filename, O_RDONLY|OpenFlags); + int FD = ::open(Filename.str().c_str(), O_RDONLY|OpenFlags); if (FD == -1) { if (ErrStr) *ErrStr = "could not open file"; return 0; @@ -203,6 +198,8 @@ // for small files, because this can severely fragment our address space. Also // don't try to map files that are exactly a multiple of the system page size, // as the file would not have the required null terminator. + // + // FIXME: Can we just mmap an extra page in the latter case? if (FileSize >= 4096*4 && (FileSize & (sys::Process::GetPageSize()-1)) != 0) { if (const char *Pages = sys::Path::MapInFilePages(FD, FileSize)) { @@ -262,6 +259,9 @@ std::vector FileData; // Read in all of the data from stdin, we cannot mmap stdin. + // + // FIXME: That isn't necessarily true, we should try to mmap stdin and + // fallback if it fails. sys::Program::ChangeStdinToBinary(); size_t ReadBytes; do { @@ -271,8 +271,6 @@ FileData.push_back(0); // &FileData[Size] is invalid. So is &*FileData.end(). size_t Size = FileData.size(); - if (Size <= 1) - return 0; MemoryBuffer *B = new STDINBufferFile(); B->initCopyOf(&FileData[0], &FileData[Size-1]); return B; Modified: llvm/trunk/lib/VMCore/Core.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=86630&r1=86629&r2=86630&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Core.cpp (original) +++ llvm/trunk/lib/VMCore/Core.cpp Mon Nov 9 18:43:58 2009 @@ -1987,13 +1987,15 @@ int LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf, char **OutMessage) { - if (MemoryBuffer *MB = MemoryBuffer::getSTDIN()) { - *OutMemBuf = wrap(MB); - return 0; + MemoryBuffer *MB = MemoryBuffer::getSTDIN(); + if (!MB->getBufferSize()) { + delete MB; + *OutMessage = strdup("stdin is empty."); + return 1; } - - *OutMessage = strdup("stdin is empty."); - return 1; + + *OutMemBuf = wrap(MB); + return 0; } void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf) { From david_goodwin at apple.com Mon Nov 9 18:48:56 2009 From: david_goodwin at apple.com (David Goodwin) Date: Tue, 10 Nov 2009 00:48:56 -0000 Subject: [llvm-commits] [llvm] r86634 - in /llvm/trunk: include/llvm/Target/TargetSubtarget.h lib/CodeGen/PostRASchedulerList.cpp lib/Target/ARM/ARMSubtarget.cpp lib/Target/ARM/ARMSubtarget.h lib/Target/TargetSubtarget.cpp lib/Target/X86/X86Subtarget.cpp lib/Target/X86/X86Subtarget.h Message-ID: <200911100048.nAA0mubl008579@zion.cs.uiuc.edu> Author: david_goodwin Date: Mon Nov 9 18:48:55 2009 New Revision: 86634 URL: http://llvm.org/viewvc/llvm-project?rev=86634&view=rev Log: Fixed to address code review. No functional changes. Modified: llvm/trunk/include/llvm/Target/TargetSubtarget.h llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp llvm/trunk/lib/Target/ARM/ARMSubtarget.h llvm/trunk/lib/Target/TargetSubtarget.cpp llvm/trunk/lib/Target/X86/X86Subtarget.cpp llvm/trunk/lib/Target/X86/X86Subtarget.h Modified: llvm/trunk/include/llvm/Target/TargetSubtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSubtarget.h?rev=86634&r1=86633&r2=86634&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetSubtarget.h (original) +++ llvm/trunk/include/llvm/Target/TargetSubtarget.h Mon Nov 9 18:48:55 2009 @@ -15,13 +15,13 @@ #define LLVM_TARGET_TARGETSUBTARGET_H #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/ADT/SmallVector.h" namespace llvm { class SDep; class SUnit; +class TargetRegisterClass; +template class SmallVectorImpl; //===----------------------------------------------------------------------===// /// @@ -38,7 +38,7 @@ // AntiDepBreakMode - Type of anti-dependence breaking that should // be performed before post-RA scheduling. typedef enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL } AntiDepBreakMode; - typedef SmallVector ExcludedRCVector; + typedef SmallVectorImpl ExcludedRCVector; virtual ~TargetSubtarget(); @@ -53,12 +53,7 @@ // return true to enable post-register-allocation scheduling. virtual bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, AntiDepBreakMode& Mode, - ExcludedRCVector& ExcludedRCs) const { - Mode = ANTIDEP_NONE; - ExcludedRCs.clear(); - return false; - } - + ExcludedRCVector& ExcludedRCs) const; // adjustSchedDependency - Perform target specific adjustments to // the latency of a schedule dependency. virtual void adjustSchedDependency(SUnit *def, SUnit *use, Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=86634&r1=86633&r2=86634&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Nov 9 18:48:55 2009 @@ -216,7 +216,7 @@ // Check for explicit enable/disable of post-ra scheduling. TargetSubtarget::AntiDepBreakMode AntiDepMode = TargetSubtarget::ANTIDEP_NONE; - TargetSubtarget::ExcludedRCVector ExcludedRCs; + SmallVector ExcludedRCs; if (EnablePostRAScheduler.getPosition() > 0) { if (!EnablePostRAScheduler) return false; Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp?rev=86634&r1=86633&r2=86634&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp Mon Nov 9 18:48:55 2009 @@ -16,6 +16,7 @@ #include "llvm/GlobalValue.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/CommandLine.h" +#include "llvm/ADT/SmallVector.h" using namespace llvm; static cl::opt @@ -159,3 +160,13 @@ return false; } + +bool ARMSubtarget::enablePostRAScheduler( + CodeGenOpt::Level OptLevel, + TargetSubtarget::AntiDepBreakMode& Mode, + ExcludedRCVector& ExcludedRCs) const { + Mode = TargetSubtarget::ANTIDEP_CRITICAL; + ExcludedRCs.clear(); + ExcludedRCs.push_back(&ARM::GPRRegClass); + return PostRAScheduler && OptLevel >= CodeGenOpt::Default; +} Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=86634&r1=86633&r2=86634&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Mon Nov 9 18:48:55 2009 @@ -127,16 +127,10 @@ const std::string & getCPUString() const { return CPUString; } - /// enablePostRAScheduler - True at 'More' optimization except - /// for Thumb1. + /// enablePostRAScheduler - True at 'More' optimization. bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, TargetSubtarget::AntiDepBreakMode& Mode, - ExcludedRCVector& ExcludedRCs) const { - Mode = TargetSubtarget::ANTIDEP_CRITICAL; - ExcludedRCs.clear(); - ExcludedRCs.push_back(&ARM::GPRRegClass); - return PostRAScheduler && OptLevel >= CodeGenOpt::Default; - } + ExcludedRCVector& ExcludedRCs) const; /// getInstrItins - Return the instruction itineraies based on subtarget /// selection. Modified: llvm/trunk/lib/Target/TargetSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetSubtarget.cpp?rev=86634&r1=86633&r2=86634&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetSubtarget.cpp (original) +++ llvm/trunk/lib/Target/TargetSubtarget.cpp Mon Nov 9 18:48:55 2009 @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/TargetSubtarget.h" +#include "llvm/ADT/SmallVector.h" using namespace llvm; //--------------------------------------------------------------------------- @@ -20,3 +21,13 @@ TargetSubtarget::TargetSubtarget() {} TargetSubtarget::~TargetSubtarget() {} + +bool TargetSubtarget::enablePostRAScheduler( + CodeGenOpt::Level OptLevel, + AntiDepBreakMode& Mode, + ExcludedRCVector& ExcludedRCs) const { + Mode = ANTIDEP_NONE; + ExcludedRCs.clear(); + return false; +} + Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=86634&r1=86633&r2=86634&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Mon Nov 9 18:48:55 2009 @@ -20,6 +20,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/ADT/SmallVector.h" using namespace llvm; #if defined(_MSC_VER) @@ -455,3 +456,12 @@ if (StackAlignment) stackAlignment = StackAlignment; } + +bool X86Subtarget::enablePostRAScheduler( + CodeGenOpt::Level OptLevel, + TargetSubtarget::AntiDepBreakMode& Mode, + ExcludedRCVector& ExcludedRCs) const { + Mode = TargetSubtarget::ANTIDEP_CRITICAL; + ExcludedRCs.clear(); + return OptLevel >= CodeGenOpt::Default; +} Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=86634&r1=86633&r2=86634&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.h (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.h Mon Nov 9 18:48:55 2009 @@ -220,11 +220,7 @@ /// at 'More' optimization level. bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, TargetSubtarget::AntiDepBreakMode& Mode, - ExcludedRCVector& ExcludedRCs) const { - Mode = TargetSubtarget::ANTIDEP_CRITICAL; - ExcludedRCs.clear(); - return OptLevel >= CodeGenOpt::Default; - } + ExcludedRCVector& ExcludedRCs) const; }; } // End llvm namespace From david_goodwin at apple.com Mon Nov 9 18:52:00 2009 From: david_goodwin at apple.com (David Goodwin) Date: Mon, 9 Nov 2009 16:52:00 -0800 Subject: [llvm-commits] [llvm] r86628 - in /llvm/trunk: include/llvm/Target/TargetSubtarget.h lib/CodeGen/AggressiveAntiDepBreaker.cpp lib/CodeGen/AggressiveAntiDepBreaker.h lib/CodeGen/PostRASchedulerList.cpp lib/Target/ARM/ARMSubtarget.h lib/Target/X86/X86Subtarget.h In-Reply-To: References: <200911100015.nAA0FmdV007190@zion.cs.uiuc.edu> Message-ID: <80411469-B27A-4B78-968B-D60C7DB43BDF@apple.com> r86634 On Nov 9, 2009, at 4:25 PM, Chris Lattner wrote: > > On Nov 9, 2009, at 4:15 PM, David Goodwin wrote: > >> Author: david_goodwin >> Date: Mon Nov 9 18:15:47 2009 >> New Revision: 86628 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=86628&view=rev >> Log: >> Allow targets to specify register classes whose member registers >> should not be renamed to break anti-dependencies. > > I don't have anything to say about the technical merits of this > patch, but... > >> +++ llvm/trunk/include/llvm/Target/TargetSubtarget.h Mon Nov 9 >> 18:15:47 2009 >> @@ -15,6 +15,8 @@ >> #define LLVM_TARGET_TARGETSUBTARGET_H >> >> #include "llvm/Target/TargetMachine.h" >> +#include "llvm/Target/TargetRegisterInfo.h" >> +#include "llvm/ADT/SmallVector.h" > > Please just forward declare what you need from these two headers > instead of #including them. Also, for APIs that take a smallvector > and fill it in, they should generally take a SmallVectorImpl > instead of specifying a size (that way the client has the ability to > pick a size). You can forward declare SmallVectorImpl like this: > > namespace llvm { > template class SmallVectorImpl; > } > > and move the virtual method out of line to avoid the .clear() in the > header. > > Thanks David, > > -Chris > >> >> namespace llvm { >> >> @@ -36,6 +38,7 @@ >> // AntiDepBreakMode - Type of anti-dependence breaking that should >> // be performed before post-RA scheduling. >> typedef enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL } >> AntiDepBreakMode; >> + typedef SmallVector ExcludedRCVector; >> >> virtual ~TargetSubtarget(); >> >> @@ -49,8 +52,10 @@ >> // scheduling and the specified optimization level meets the >> requirement >> // return true to enable post-register-allocation scheduling. >> virtual bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, >> - AntiDepBreakMode& mode) const { >> - mode = ANTIDEP_NONE; >> + AntiDepBreakMode& Mode, >> + ExcludedRCVector& >> ExcludedRCs) const { >> + Mode = ANTIDEP_NONE; >> + ExcludedRCs.clear(); >> return false; >> } >> >> >> Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp?rev=86628&r1=86627&r2=86628&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp (original) >> +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp Mon Nov 9 >> 18:15:47 2009 >> @@ -99,12 +99,24 @@ >> >> >> AggressiveAntiDepBreaker:: >> -AggressiveAntiDepBreaker(MachineFunction& MFi) : >> +AggressiveAntiDepBreaker(MachineFunction& MFi, >> + TargetSubtarget::ExcludedRCVector& >> ExcludedRCs) : >> AntiDepBreaker(), MF(MFi), >> MRI(MF.getRegInfo()), >> TRI(MF.getTarget().getRegisterInfo()), >> AllocatableSet(TRI->getAllocatableSet(MF)), >> State(NULL), SavedState(NULL) { >> + /* Remove all registers from excluded RCs from the allocatable >> + register set. */ >> + for (unsigned i = 0, e = ExcludedRCs.size(); i < e; ++i) { >> + BitVector NotRenameable = TRI->getAllocatableSet(MF, >> ExcludedRCs[i]).flip(); >> + AllocatableSet &= NotRenameable; >> + } >> + >> + DEBUG(errs() << "AntiDep Renameable Registers:"); >> + DEBUG(for (int r = AllocatableSet.find_first(); r != -1; >> + r = AllocatableSet.find_next(r)) >> + errs() << " " << TRI->getName(r)); >> } >> >> AggressiveAntiDepBreaker::~AggressiveAntiDepBreaker() { >> >> Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h?rev=86628&r1=86627&r2=86628&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h (original) >> +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h Mon Nov 9 >> 18:15:47 2009 >> @@ -23,6 +23,7 @@ >> #include "llvm/CodeGen/MachineFunction.h" >> #include "llvm/CodeGen/MachineRegisterInfo.h" >> #include "llvm/CodeGen/ScheduleDAG.h" >> +#include "llvm/Target/TargetSubtarget.h" >> #include "llvm/Target/TargetRegisterInfo.h" >> #include "llvm/ADT/BitVector.h" >> #include "llvm/ADT/SmallSet.h" >> @@ -112,7 +113,7 @@ >> /// AllocatableSet - The set of allocatable registers. >> /// We'll be ignoring anti-dependencies on non-allocatable >> registers, >> /// because they may not be safe to break. >> - const BitVector AllocatableSet; >> + BitVector AllocatableSet; >> >> /// State - The state used to identify and rename anti-dependence >> /// registers. >> @@ -124,7 +125,8 @@ >> AggressiveAntiDepState *SavedState; >> >> public: >> - AggressiveAntiDepBreaker(MachineFunction& MFi); >> + AggressiveAntiDepBreaker(MachineFunction& MFi, >> + TargetSubtarget::ExcludedRCVector& >> ExcludedRCs); >> ~AggressiveAntiDepBreaker(); >> >> /// GetMaxTrials - As anti-dependencies are broken, additional >> >> Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=86628&r1=86627&r2=86628&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) >> +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Nov 9 >> 18:15:47 2009 >> @@ -216,13 +216,14 @@ >> >> // Check for explicit enable/disable of post-ra scheduling. >> TargetSubtarget::AntiDepBreakMode AntiDepMode = >> TargetSubtarget::ANTIDEP_NONE; >> + TargetSubtarget::ExcludedRCVector ExcludedRCs; >> if (EnablePostRAScheduler.getPosition() > 0) { >> if (!EnablePostRAScheduler) >> return false; >> } else { >> // Check that post-RA scheduling is enabled for this target. >> const TargetSubtarget &ST = Fn.getTarget >> ().getSubtarget(); >> - if (!ST.enablePostRAScheduler(OptLevel, AntiDepMode)) >> + if (!ST.enablePostRAScheduler(OptLevel, AntiDepMode, >> ExcludedRCs)) >> return false; >> } >> >> @@ -243,7 +244,7 @@ >> (ScheduleHazardRecognizer *)new SimpleHazardRecognizer(); >> AntiDepBreaker *ADB = >> ((AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? >> - (AntiDepBreaker *)new AggressiveAntiDepBreaker(Fn) : >> + (AntiDepBreaker *)new AggressiveAntiDepBreaker(Fn, >> ExcludedRCs) : >> ((AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? >> (AntiDepBreaker *)new CriticalAntiDepBreaker(Fn) : NULL)); >> >> >> Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=86628&r1=86627&r2=86628&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) >> +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Mon Nov 9 18:15:47 2009 >> @@ -17,6 +17,7 @@ >> #include "llvm/Target/TargetInstrItineraries.h" >> #include "llvm/Target/TargetMachine.h" >> #include "llvm/Target/TargetSubtarget.h" >> +#include "ARMBaseRegisterInfo.h" >> #include >> >> namespace llvm { >> @@ -129,8 +130,11 @@ >> /// enablePostRAScheduler - True at 'More' optimization except >> /// for Thumb1. >> bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, >> - TargetSubtarget::AntiDepBreakMode& >> mode) const { >> - mode = TargetSubtarget::ANTIDEP_CRITICAL; >> + TargetSubtarget::AntiDepBreakMode& >> Mode, >> + ExcludedRCVector& ExcludedRCs) const { >> + Mode = TargetSubtarget::ANTIDEP_CRITICAL; >> + ExcludedRCs.clear(); >> + ExcludedRCs.push_back(&ARM::GPRRegClass); >> return PostRAScheduler && OptLevel >= CodeGenOpt::Default; >> } >> >> >> Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=86628&r1=86627&r2=86628&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/X86/X86Subtarget.h (original) >> +++ llvm/trunk/lib/Target/X86/X86Subtarget.h Mon Nov 9 18:15:47 2009 >> @@ -219,8 +219,10 @@ >> /// enablePostRAScheduler - X86 target is enabling post-alloc >> scheduling >> /// at 'More' optimization level. >> bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, >> - TargetSubtarget::AntiDepBreakMode& >> mode) const { >> - mode = TargetSubtarget::ANTIDEP_CRITICAL; >> + TargetSubtarget::AntiDepBreakMode& >> Mode, >> + ExcludedRCVector& ExcludedRCs) const { >> + Mode = TargetSubtarget::ANTIDEP_CRITICAL; >> + ExcludedRCs.clear(); >> return OptLevel >= CodeGenOpt::Default; >> } >> }; >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From sabre at nondot.org Mon Nov 9 18:55:13 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 00:55:13 -0000 Subject: [llvm-commits] [llvm] r86635 - in /llvm/trunk: include/llvm/Analysis/InstructionSimplify.h lib/Analysis/InstructionSimplify.cpp lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200911100055.nAA0tDln008794@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 18:55:12 2009 New Revision: 86635 URL: http://llvm.org/viewvc/llvm-project?rev=86635&view=rev Log: factor simplification logic for AND and OR out to InstSimplify from instcombine. Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionSimplify.h?rev=86635&r1=86634&r2=86635&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h (original) +++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Mon Nov 9 18:55:12 2009 @@ -20,15 +20,26 @@ class Value; class TargetData; + + /// SimplifyAndInst - Given operands for an And, see if we can + /// fold the result. If not, this returns null. + Value *SimplifyAndInst(Value *LHS, Value *RHS, + const TargetData *TD = 0); + + /// SimplifyOrInst - Given operands for an Or, see if we can + /// fold the result. If not, this returns null. + Value *SimplifyOrInst(Value *LHS, Value *RHS, + const TargetData *TD = 0); + /// SimplifyICmpInst - Given operands for an ICmpInst, see if we can /// fold the result. If not, this returns null. Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const TargetData *TD = 0); + const TargetData *TD = 0); /// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can /// fold the result. If not, this returns null. Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const TargetData *TD = 0); + const TargetData *TD = 0); //=== Helper functions for higher up the class hierarchy. Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=86635&r1=86634&r2=86635&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Mon Nov 9 18:55:12 2009 @@ -16,21 +16,133 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Instructions.h" +#include "llvm/Support/PatternMatch.h" using namespace llvm; +using namespace llvm::PatternMatch; +/// SimplifyAndInst - Given operands for an And, see if we can +/// fold the result. If not, this returns null. +Value *llvm::SimplifyAndInst(Value *Op0, Value *Op1, + const TargetData *TD) { + if (Constant *CLHS = dyn_cast(Op0)) { + if (Constant *CRHS = dyn_cast(Op1)) { + Constant *Ops[] = { CLHS, CRHS }; + return ConstantFoldInstOperands(Instruction::And, CLHS->getType(), + Ops, 2, TD); + } + + // Canonicalize the constant to the RHS. + std::swap(Op0, Op1); + } + + // X & undef -> 0 + if (isa(Op1)) + return Constant::getNullValue(Op0->getType()); + + // X & X = X + if (Op0 == Op1) + return Op0; + + // X & <0,0> = <0,0> + if (isa(Op1)) + return Op1; + + // X & <-1,-1> = X + if (ConstantVector *CP = dyn_cast(Op1)) + if (CP->isAllOnesValue()) + return Op0; + + if (ConstantInt *Op1CI = dyn_cast(Op1)) { + // X & 0 = 0 + if (Op1CI->isZero()) + return Op1CI; + // X & -1 = X + if (Op1CI->isAllOnesValue()) + return Op0; + } + + // A & ~A = ~A & A = 0 + Value *A, *B; + if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || + (match(Op1, m_Not(m_Value(A))) && A == Op0)) + return Constant::getNullValue(Op0->getType()); + + // (A | ?) & A = A + if (match(Op0, m_Or(m_Value(A), m_Value(B))) && + (A == Op1 || B == Op1)) + return Op1; + + // A & (A | ?) = A + if (match(Op1, m_Or(m_Value(A), m_Value(B))) && + (A == Op0 || B == Op0)) + return Op0; + + return 0; +} -/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can +/// SimplifyOrInst - Given operands for an Or, see if we can /// fold the result. If not, this returns null. -Value *llvm::SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, - const TargetData *TD) { - if (Constant *CLHS = dyn_cast(LHS)) - if (Constant *CRHS = dyn_cast(RHS)) { - Constant *COps[] = {CLHS, CRHS}; - return ConstantFoldInstOperands(Opcode, LHS->getType(), COps, 2, TD); - } +Value *llvm::SimplifyOrInst(Value *Op0, Value *Op1, + const TargetData *TD) { + if (Constant *CLHS = dyn_cast(Op0)) { + if (Constant *CRHS = dyn_cast(Op1)) { + Constant *Ops[] = { CLHS, CRHS }; + return ConstantFoldInstOperands(Instruction::Or, CLHS->getType(), + Ops, 2, TD); + } + + // Canonicalize the constant to the RHS. + std::swap(Op0, Op1); + } + + // X | undef -> -1 + if (isa(Op1)) + return Constant::getAllOnesValue(Op0->getType()); + + // X | X = X + if (Op0 == Op1) + return Op0; + + // X | <0,0> = X + if (isa(Op1)) + return Op0; + + // X | <-1,-1> = <-1,-1> + if (ConstantVector *CP = dyn_cast(Op1)) + if (CP->isAllOnesValue()) + return Op1; + + if (ConstantInt *Op1CI = dyn_cast(Op1)) { + // X | 0 = X + if (Op1CI->isZero()) + return Op0; + // X | -1 = -1 + if (Op1CI->isAllOnesValue()) + return Op1CI; + } + + // A | ~A = ~A | A = -1 + Value *A, *B; + if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || + (match(Op1, m_Not(m_Value(A))) && A == Op0)) + return Constant::getAllOnesValue(Op0->getType()); + + // (A & ?) | A = A + if (match(Op0, m_And(m_Value(A), m_Value(B))) && + (A == Op1 || B == Op1)) + return Op1; + + // A | (A & ?) = A + if (match(Op1, m_And(m_Value(A), m_Value(B))) && + (A == Op0 || B == Op0)) + return Op0; + return 0; } + + + static const Type *GetCompareTy(Value *Op) { return CmpInst::makeCmpResultType(Op->getType()); } @@ -43,9 +155,14 @@ CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate; assert(CmpInst::isIntPredicate(Pred) && "Not an integer compare!"); - if (Constant *CLHS = dyn_cast(LHS)) + if (Constant *CLHS = dyn_cast(LHS)) { if (Constant *CRHS = dyn_cast(RHS)) return ConstantFoldCompareInstOperands(Pred, CLHS, CRHS, TD); + + // If we have a constant, make sure it is on the RHS. + std::swap(LHS, RHS); + Pred = CmpInst::getSwappedPredicate(Pred); + } // ITy - This is the return type of the compare we're considering. const Type *ITy = GetCompareTy(LHS); @@ -54,12 +171,6 @@ if (LHS == RHS) return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred)); - // If we have a constant, make sure it is on the RHS. - if (isa(LHS)) { - std::swap(LHS, RHS); - Pred = CmpInst::getSwappedPredicate(Pred); - } - if (isa(RHS)) // X icmp undef -> undef return UndefValue::get(ITy); @@ -95,8 +206,6 @@ return ConstantInt::getTrue(CI->getContext()); break; } - - } @@ -110,9 +219,14 @@ CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate; assert(CmpInst::isFPPredicate(Pred) && "Not an FP compare!"); - if (Constant *CLHS = dyn_cast(LHS)) + if (Constant *CLHS = dyn_cast(LHS)) { if (Constant *CRHS = dyn_cast(RHS)) return ConstantFoldCompareInstOperands(Pred, CLHS, CRHS, TD); + + // If we have a constant, make sure it is on the RHS. + std::swap(LHS, RHS); + Pred = CmpInst::getSwappedPredicate(Pred); + } // Fold trivial predicates. if (Pred == FCmpInst::FCMP_FALSE) @@ -120,12 +234,6 @@ if (Pred == FCmpInst::FCMP_TRUE) return ConstantInt::get(GetCompareTy(LHS), 1); - // If we have a constant, make sure it is on the RHS. - if (isa(LHS)) { - std::swap(LHS, RHS); - Pred = CmpInst::getSwappedPredicate(Pred); - } - if (isa(RHS)) // fcmp pred X, undef -> undef return UndefValue::get(GetCompareTy(LHS)); @@ -155,7 +263,24 @@ return 0; } +//=== Helper functions for higher up the class hierarchy. +/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can +/// fold the result. If not, this returns null. +Value *llvm::SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, + const TargetData *TD) { + switch (Opcode) { + case Instruction::And: return SimplifyAndInst(LHS, RHS, TD); + case Instruction::Or: return SimplifyOrInst(LHS, RHS, TD); + default: + if (Constant *CLHS = dyn_cast(LHS)) + if (Constant *CRHS = dyn_cast(RHS)) { + Constant *COps[] = {CLHS, CRHS}; + return ConstantFoldInstOperands(Opcode, LHS->getType(), COps, 2, TD); + } + return 0; + } +} /// SimplifyCmpInst - Given operands for a CmpInst, see if we can /// fold the result. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=86635&r1=86634&r2=86635&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Nov 9 18:55:12 2009 @@ -4292,25 +4292,15 @@ bool Changed = SimplifyCommutative(I); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - if (isa(Op1)) // X & undef -> 0 - return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - - // and X, X = X - if (Op0 == Op1) - return ReplaceInstUsesWith(I, Op1); + if (Value *V = SimplifyAndInst(Op0, Op1, TD)) + return ReplaceInstUsesWith(I, V); + // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. if (SimplifyDemandedInstructionBits(I)) return &I; - if (isa(I.getType())) { - if (ConstantVector *CP = dyn_cast(Op1)) { - if (CP->isAllOnesValue()) // X & <-1,-1> -> X - return ReplaceInstUsesWith(I, I.getOperand(0)); - } else if (isa(Op1)) { - return ReplaceInstUsesWith(I, Op1); // X & <0,0> -> <0,0> - } - } + if (ConstantInt *AndRHS = dyn_cast(Op1)) { const APInt &AndRHSMask = AndRHS->getValue(); @@ -4431,42 +4421,29 @@ return NV; } - Value *Op0NotVal = dyn_castNotVal(Op0); - Value *Op1NotVal = dyn_castNotVal(Op1); - - if (Op0NotVal == Op1 || Op1NotVal == Op0) // A & ~A == ~A & A == 0 - return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); // (~A & ~B) == (~(A | B)) - De Morgan's Law - if (Op0NotVal && Op1NotVal && isOnlyUse(Op0) && isOnlyUse(Op1)) { - Value *Or = Builder->CreateOr(Op0NotVal, Op1NotVal, - I.getName()+".demorgan"); - return BinaryOperator::CreateNot(Or); - } - + if (Value *Op0NotVal = dyn_castNotVal(Op0)) + if (Value *Op1NotVal = dyn_castNotVal(Op1)) + if (Op0->hasOneUse() && Op1->hasOneUse()) { + Value *Or = Builder->CreateOr(Op0NotVal, Op1NotVal, + I.getName()+".demorgan"); + return BinaryOperator::CreateNot(Or); + } + { Value *A = 0, *B = 0, *C = 0, *D = 0; - if (match(Op0, m_Or(m_Value(A), m_Value(B)))) { - if (A == Op1 || B == Op1) // (A | ?) & A --> A - return ReplaceInstUsesWith(I, Op1); - - // (A|B) & ~(A&B) -> A^B - if (match(Op1, m_Not(m_And(m_Value(C), m_Value(D))))) { - if ((A == C && B == D) || (A == D && B == C)) - return BinaryOperator::CreateXor(A, B); - } - } + // (A|B) & ~(A&B) -> A^B + if (match(Op0, m_Or(m_Value(A), m_Value(B))) && + match(Op1, m_Not(m_And(m_Value(C), m_Value(D)))) && + ((A == C && B == D) || (A == D && B == C))) + return BinaryOperator::CreateXor(A, B); - if (match(Op1, m_Or(m_Value(A), m_Value(B)))) { - if (A == Op0 || B == Op0) // A & (A | ?) --> A - return ReplaceInstUsesWith(I, Op0); - - // ~(A&B) & (A|B) -> A^B - if (match(Op0, m_Not(m_And(m_Value(C), m_Value(D))))) { - if ((A == C && B == D) || (A == D && B == C)) - return BinaryOperator::CreateXor(A, B); - } - } + // ~(A&B) & (A|B) -> A^B + if (match(Op1, m_Or(m_Value(A), m_Value(B))) && + match(Op0, m_Not(m_And(m_Value(C), m_Value(D)))) && + ((A == C && B == D) || (A == D && B == C))) + return BinaryOperator::CreateXor(A, B); if (Op0->hasOneUse() && match(Op0, m_Xor(m_Value(A), m_Value(B)))) { @@ -4998,27 +4975,15 @@ bool Changed = SimplifyCommutative(I); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - if (isa(Op1)) // X | undef -> -1 - return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); - - // or X, X = X - if (Op0 == Op1) - return ReplaceInstUsesWith(I, Op0); - + if (Value *V = SimplifyOrInst(Op0, Op1, TD)) + return ReplaceInstUsesWith(I, V); + + // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. if (SimplifyDemandedInstructionBits(I)) return &I; - if (isa(I.getType())) { - if (isa(Op1)) { - return ReplaceInstUsesWith(I, Op0); // X | <0,0> -> X - } else if (ConstantVector *CP = dyn_cast(Op1)) { - if (CP->isAllOnesValue()) // X | <-1,-1> -> <-1,-1> - return ReplaceInstUsesWith(I, I.getOperand(1)); - } - } - // or X, -1 == -1 if (ConstantInt *RHS = dyn_cast(Op1)) { ConstantInt *C1 = 0; Value *X = 0; // (X & C1) | C2 --> (X | C2) & (C1|C2) @@ -5051,13 +5016,6 @@ Value *A = 0, *B = 0; ConstantInt *C1 = 0, *C2 = 0; - if (match(Op0, m_And(m_Value(A), m_Value(B)))) - if (A == Op1 || B == Op1) // (A & ?) | A --> A - return ReplaceInstUsesWith(I, Op1); - if (match(Op1, m_And(m_Value(A), m_Value(B)))) - if (A == Op0 || B == Op0) // A | (A & ?) --> A - return ReplaceInstUsesWith(I, Op0); - // (A | B) | C and A | (B | C) -> bswap if possible. // (A >> B) | (C << D) and (A << B) | (B >> C) -> bswap if possible. if (match(Op0, m_Or(m_Value(), m_Value())) || @@ -5191,23 +5149,14 @@ if (Ret) return Ret; } - if ((A = dyn_castNotVal(Op0))) { // ~A | Op1 - if (A == Op1) // ~A | A == -1 - return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); - } else { - A = 0; - } - // Note, A is still live here! - if ((B = dyn_castNotVal(Op1))) { // Op0 | ~B - if (Op0 == B) - return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); - - // (~A | ~B) == (~(A & B)) - De Morgan's Law - if (A && isOnlyUse(Op0) && isOnlyUse(Op1)) { - Value *And = Builder->CreateAnd(A, B, I.getName()+".demorgan"); - return BinaryOperator::CreateNot(And); - } - } + // (~A | ~B) == (~(A & B)) - De Morgan's Law + if (Value *Op0NotVal = dyn_castNotVal(Op0)) + if (Value *Op1NotVal = dyn_castNotVal(Op1)) + if (Op0->hasOneUse() && Op1->hasOneUse()) { + Value *And = Builder->CreateAnd(Op0NotVal, Op1NotVal, + I.getName()+".demorgan"); + return BinaryOperator::CreateNot(And); + } // (icmp1 A, B) | (icmp2 A, B) --> (icmp3 A, B) if (ICmpInst *RHS = dyn_cast(I.getOperand(1))) { From jyasskin at google.com Mon Nov 9 19:02:18 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Tue, 10 Nov 2009 01:02:18 -0000 Subject: [llvm-commits] [llvm] r86636 - in /llvm/trunk: include/llvm/ADT/DenseMap.h include/llvm/Analysis/SparsePropagation.h include/llvm/Support/type_traits.h lib/Analysis/IPA/Andersens.cpp lib/CodeGen/AsmPrinter/DwarfException.cpp lib/CodeGen/PreAllocSplitting.cpp lib/CodeGen/SlotIndexes.cpp lib/Target/MSP430/MSP430ISelDAGToDAG.cpp lib/Target/X86/X86InstrInfo.cpp lib/Transforms/Scalar/ABCD.cpp lib/Transforms/Scalar/GVN.cpp lib/Transforms/Scalar/SCCVN.cpp lib/VMCore/Metadata.cpp unittests/ADT/DenseMapTest.cpp Message-ID: <200911100102.nAA12ITk009096@zion.cs.uiuc.edu> Author: jyasskin Date: Mon Nov 9 19:02:17 2009 New Revision: 86636 URL: http://llvm.org/viewvc/llvm-project?rev=86636&view=rev Log: Fix DenseMap iterator constness. This patch forbids implicit conversion of DenseMap::const_iterator to DenseMap::iterator which was possible because DenseMapIterator inherited (publicly) from DenseMapConstIterator. Conversion the other way around is now allowed as one may expect. The template DenseMapConstIterator is removed and the template parameter IsConst which specifies whether the iterator is constant is added to DenseMapIterator. Actually IsConst parameter is not necessary since the constness can be determined from KeyT but this is not relevant to the fix and can be addressed later. Patch by Victor Zverovich! Modified: llvm/trunk/include/llvm/ADT/DenseMap.h llvm/trunk/include/llvm/Analysis/SparsePropagation.h llvm/trunk/include/llvm/Support/type_traits.h llvm/trunk/lib/Analysis/IPA/Andersens.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp llvm/trunk/lib/CodeGen/SlotIndexes.cpp llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Transforms/Scalar/ABCD.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp llvm/trunk/lib/VMCore/Metadata.cpp llvm/trunk/unittests/ADT/DenseMapTest.cpp Modified: llvm/trunk/include/llvm/ADT/DenseMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/DenseMap.h (original) +++ llvm/trunk/include/llvm/ADT/DenseMap.h Mon Nov 9 19:02:17 2009 @@ -14,8 +14,9 @@ #ifndef LLVM_ADT_DENSEMAP_H #define LLVM_ADT_DENSEMAP_H -#include "llvm/Support/PointerLikeTypeTraits.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/PointerLikeTypeTraits.h" +#include "llvm/Support/type_traits.h" #include "llvm/ADT/DenseMapInfo.h" #include #include @@ -27,12 +28,8 @@ template, - typename ValueInfoT = DenseMapInfo > + typename ValueInfoT = DenseMapInfo, bool IsConst = false> class DenseMapIterator; -template, - typename ValueInfoT = DenseMapInfo > -class DenseMapConstIterator; template, @@ -73,7 +70,8 @@ } typedef DenseMapIterator iterator; - typedef DenseMapConstIterator const_iterator; + typedef DenseMapIterator const_iterator; inline iterator begin() { return iterator(Buckets, Buckets+NumBuckets); } @@ -426,32 +424,47 @@ } }; -template -class DenseMapIterator : - public std::iterator, - ptrdiff_t> { - typedef std::pair BucketT; -protected: - const BucketT *Ptr, *End; +template +class DenseMapIterator { + typedef std::pair Bucket; + typedef DenseMapIterator ConstIterator; + friend class DenseMapIterator; +public: + typedef ptrdiff_t difference_type; + typedef typename conditional::type value_type; + typedef value_type *pointer; + typedef value_type &reference; + typedef std::forward_iterator_tag iterator_category; +private: + pointer Ptr, End; public: DenseMapIterator() : Ptr(0), End(0) {} - DenseMapIterator(const BucketT *Pos, const BucketT *E) : Ptr(Pos), End(E) { + DenseMapIterator(pointer Pos, pointer E) : Ptr(Pos), End(E) { AdvancePastEmptyBuckets(); } - std::pair &operator*() const { - return *const_cast(Ptr); + // If IsConst is true this is a converting constructor from iterator to + // const_iterator and the default copy constructor is used. + // Otherwise this is a copy constructor for iterator. + DenseMapIterator(const DenseMapIterator& I) + : Ptr(I.Ptr), End(I.End) {} + + reference operator*() const { + return *Ptr; } - std::pair *operator->() const { - return const_cast(Ptr); + pointer operator->() const { + return Ptr; } - bool operator==(const DenseMapIterator &RHS) const { - return Ptr == RHS.Ptr; + bool operator==(const ConstIterator &RHS) const { + return Ptr == RHS.operator->(); } - bool operator!=(const DenseMapIterator &RHS) const { - return Ptr != RHS.Ptr; + bool operator!=(const ConstIterator &RHS) const { + return Ptr != RHS.operator->(); } inline DenseMapIterator& operator++() { // Preincrement @@ -475,22 +488,6 @@ } }; -template -class DenseMapConstIterator : public DenseMapIterator { -public: - DenseMapConstIterator() : DenseMapIterator() {} - DenseMapConstIterator(const std::pair *Pos, - const std::pair *E) - : DenseMapIterator(Pos, E) { - } - const std::pair &operator*() const { - return *this->Ptr; - } - const std::pair *operator->() const { - return this->Ptr; - } -}; - } // end namespace llvm #endif Modified: llvm/trunk/include/llvm/Analysis/SparsePropagation.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/SparsePropagation.h?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/SparsePropagation.h (original) +++ llvm/trunk/include/llvm/Analysis/SparsePropagation.h Mon Nov 9 19:02:17 2009 @@ -153,7 +153,7 @@ /// value. If an value is not in the map, it is returned as untracked, /// unlike the getOrInitValueState method. LatticeVal getLatticeState(Value *V) const { - DenseMap::iterator I = ValueState.find(V); + DenseMap::const_iterator I = ValueState.find(V); return I != ValueState.end() ? I->second : LatticeFunc->getUntrackedVal(); } Modified: llvm/trunk/include/llvm/Support/type_traits.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/type_traits.h?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/type_traits.h (original) +++ llvm/trunk/include/llvm/Support/type_traits.h Mon Nov 9 19:02:17 2009 @@ -96,6 +96,12 @@ template struct remove_pointer { typedef T type; }; +template +struct conditional { typedef T type; }; + +template +struct conditional { typedef F type; }; + } #endif Modified: llvm/trunk/lib/Analysis/IPA/Andersens.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/Andersens.cpp?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IPA/Andersens.cpp (original) +++ llvm/trunk/lib/Analysis/IPA/Andersens.cpp Mon Nov 9 19:02:17 2009 @@ -518,7 +518,7 @@ /// getObject - Return the node corresponding to the memory object for the /// specified global or allocation instruction. unsigned getObject(Value *V) const { - DenseMap::iterator I = ObjectNodes.find(V); + DenseMap::const_iterator I = ObjectNodes.find(V); assert(I != ObjectNodes.end() && "Value does not have an object in the points-to graph!"); return I->second; @@ -527,7 +527,7 @@ /// getReturnNode - Return the node representing the return value for the /// specified function. unsigned getReturnNode(Function *F) const { - DenseMap::iterator I = ReturnNodes.find(F); + DenseMap::const_iterator I = ReturnNodes.find(F); assert(I != ReturnNodes.end() && "Function does not return a value!"); return I->second; } @@ -535,7 +535,7 @@ /// getVarargNode - Return the node representing the variable arguments /// formal for the specified function. unsigned getVarargNode(Function *F) const { - DenseMap::iterator I = VarargNodes.find(F); + DenseMap::const_iterator I = VarargNodes.find(F); assert(I != VarargNodes.end() && "Function does not take var args!"); return I->second; } Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Mon Nov 9 19:02:17 2009 @@ -497,7 +497,7 @@ SawPotentiallyThrowing = false; // Beginning of a new try-range? - RangeMapType::iterator L = PadMap.find(BeginLabel); + RangeMapType::const_iterator L = PadMap.find(BeginLabel); if (L == PadMap.end()) // Nope, it was just some random label. continue; Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp (original) +++ llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Mon Nov 9 19:02:17 2009 @@ -366,10 +366,10 @@ if (!DefMBB) return false; - DenseMap::iterator I = IntervalSSMap.find(Reg); + DenseMap::const_iterator I = IntervalSSMap.find(Reg); if (I == IntervalSSMap.end()) return false; - DenseMap::iterator + DenseMap::const_iterator II = Def2SpillMap.find(DefIndex); if (II == Def2SpillMap.end()) return false; Modified: llvm/trunk/lib/CodeGen/SlotIndexes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SlotIndexes.cpp?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SlotIndexes.cpp (original) +++ llvm/trunk/lib/CodeGen/SlotIndexes.cpp Mon Nov 9 19:02:17 2009 @@ -201,7 +201,7 @@ } } - for (MBB2IdxMap::iterator itr = mbb2IdxMap.begin(); + for (MBB2IdxMap::const_iterator itr = mbb2IdxMap.begin(); itr != mbb2IdxMap.end(); ++itr) { errs() << "MBB " << itr->first->getNumber() << " (" << itr->first << ") - [" << itr->second.first << ", " << itr->second.second << "]\n"; Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp Mon Nov 9 19:02:17 2009 @@ -364,7 +364,7 @@ /// TokenFactor by PreprocessForRMW. Query the map Store => Load1 (created /// during preprocessing) to determine whether it's legal to introduce such /// "cycle" for a moment. - DenseMap::iterator I = RMWStores.find(Root); + DenseMap::const_iterator I = RMWStores.find(Root); if (I != RMWStores.end() && I->second == N) return true; Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon Nov 9 19:02:17 2009 @@ -2170,7 +2170,7 @@ // If table selected... if (OpcodeTablePtr) { // Find the Opcode to fuse - DenseMap >::iterator I = + DenseMap >::const_iterator I = OpcodeTablePtr->find((unsigned*)MI->getOpcode()); if (I != OpcodeTablePtr->end()) { unsigned Opcode = I->second.first; @@ -2402,7 +2402,7 @@ if (OpcodeTablePtr) { // Find the Opcode to fuse - DenseMap >::iterator I = + DenseMap >::const_iterator I = OpcodeTablePtr->find((unsigned*)Opc); if (I != OpcodeTablePtr->end()) return true; @@ -2413,7 +2413,7 @@ bool X86InstrInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, unsigned Reg, bool UnfoldLoad, bool UnfoldStore, SmallVectorImpl &NewMIs) const { - DenseMap >::iterator I = + DenseMap >::const_iterator I = MemOp2RegOpTable.find((unsigned*)MI->getOpcode()); if (I == MemOp2RegOpTable.end()) return false; @@ -2530,7 +2530,7 @@ if (!N->isMachineOpcode()) return false; - DenseMap >::iterator I = + DenseMap >::const_iterator I = MemOp2RegOpTable.find((unsigned*)N->getMachineOpcode()); if (I == MemOp2RegOpTable.end()) return false; @@ -2623,7 +2623,7 @@ unsigned X86InstrInfo::getOpcodeAfterMemoryUnfold(unsigned Opc, bool UnfoldLoad, bool UnfoldStore, unsigned *LoadRegIndex) const { - DenseMap >::iterator I = + DenseMap >::const_iterator I = MemOp2RegOpTable.find((unsigned*)Opc); if (I == MemOp2RegOpTable.end()) return 0; Modified: llvm/trunk/lib/Transforms/Scalar/ABCD.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ABCD.cpp?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ABCD.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ABCD.cpp Mon Nov 9 19:02:17 2009 @@ -1049,7 +1049,7 @@ /// Prints the body of the dot file void ABCD::InequalityGraph::printBody(raw_ostream &OS) const { - DenseMap >::iterator begin = + DenseMap >::const_iterator begin = graph.begin(), end = graph.end(); for (; begin != end ; ++begin) { Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Mon Nov 9 19:02:17 2009 @@ -624,7 +624,7 @@ /// lookup - Returns the value number of the specified value. Fails if /// the value has not yet been numbered. uint32_t ValueTable::lookup(Value *V) const { - DenseMap::iterator VI = valueNumbering.find(V); + DenseMap::const_iterator VI = valueNumbering.find(V); assert(VI != valueNumbering.end() && "Value not numbered?"); return VI->second; } @@ -644,7 +644,7 @@ /// verifyRemoved - Verify that the value is removed from all internal data /// structures. void ValueTable::verifyRemoved(const Value *V) const { - for (DenseMap::iterator + for (DenseMap::const_iterator I = valueNumbering.begin(), E = valueNumbering.end(); I != E; ++I) { assert(I->first != V && "Inst still occurs in value numbering map!"); } @@ -2011,12 +2011,12 @@ // Walk through the value number scope to make sure the instruction isn't // ferreted away in it. - for (DenseMap::iterator + for (DenseMap::const_iterator I = localAvail.begin(), E = localAvail.end(); I != E; ++I) { const ValueNumberScope *VNS = I->second; while (VNS) { - for (DenseMap::iterator + for (DenseMap::const_iterator II = VNS->table.begin(), IE = VNS->table.end(); II != IE; ++II) { assert(II->second != Inst && "Inst still in value numbering scope!"); } Modified: llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp Mon Nov 9 19:02:17 2009 @@ -507,7 +507,7 @@ /// verifyRemoved - Verify that the value is removed from all internal data /// structures. void ValueTable::verifyRemoved(const Value *V) const { - for (DenseMap::iterator + for (DenseMap::const_iterator I = valueNumbering.begin(), E = valueNumbering.end(); I != E; ++I) { assert(I->first != V && "Inst still occurs in value numbering map!"); } Modified: llvm/trunk/lib/VMCore/Metadata.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Metadata.cpp?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Metadata.cpp (original) +++ llvm/trunk/lib/VMCore/Metadata.cpp Mon Nov 9 19:02:17 2009 @@ -341,11 +341,11 @@ /// getMDs - Get the metadata attached to an Instruction. void MetadataContextImpl:: getMDs(const Instruction *Inst, SmallVectorImpl &MDs) const { - MDStoreTy::iterator I = MetadataStore.find(Inst); + MDStoreTy::const_iterator I = MetadataStore.find(Inst); if (I == MetadataStore.end()) return; MDs.resize(I->second.size()); - for (MDMapTy::iterator MI = I->second.begin(), ME = I->second.end(); + for (MDMapTy::const_iterator MI = I->second.begin(), ME = I->second.end(); MI != ME; ++MI) // MD kinds are numbered from 1. MDs[MI->first - 1] = std::make_pair(MI->first, MI->second); Modified: llvm/trunk/unittests/ADT/DenseMapTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/DenseMapTest.cpp?rev=86636&r1=86635&r2=86636&view=diff ============================================================================== --- llvm/trunk/unittests/ADT/DenseMapTest.cpp (original) +++ llvm/trunk/unittests/ADT/DenseMapTest.cpp Mon Nov 9 19:02:17 2009 @@ -164,4 +164,16 @@ } } +// const_iterator test +TEST_F(DenseMapTest, ConstIteratorTest) { + // Check conversion from iterator to const_iterator. + DenseMap::iterator it = uintMap.begin(); + DenseMap::const_iterator cit(it); + EXPECT_TRUE(it == cit); + + // Check copying of const_iterators. + DenseMap::const_iterator cit2(cit); + EXPECT_TRUE(cit == cit2); +} + } From clattner at apple.com Mon Nov 9 19:04:53 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 9 Nov 2009 17:04:53 -0800 Subject: [llvm-commits] [llvm] r86628 - in /llvm/trunk: include/llvm/Target/TargetSubtarget.h lib/CodeGen/AggressiveAntiDepBreaker.cpp lib/CodeGen/AggressiveAntiDepBreaker.h lib/CodeGen/PostRASchedulerList.cpp lib/Target/ARM/ARMSubtarget.h lib/Target/X86/X86Subtarget.h In-Reply-To: <80411469-B27A-4B78-968B-D60C7DB43BDF@apple.com> References: <200911100015.nAA0FmdV007190@zion.cs.uiuc.edu> <80411469-B27A-4B78-968B-D60C7DB43BDF@apple.com> Message-ID: <43FA9A68-ADC7-405A-B405-C2BA7F75600F@apple.com> On Nov 9, 2009, at 4:52 PM, David Goodwin wrote: > r86634 Thanks David! From sabre at nondot.org Mon Nov 9 19:08:51 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 01:08:51 -0000 Subject: [llvm-commits] [llvm] r86637 - in /llvm/trunk: include/llvm/Analysis/InstructionSimplify.h lib/Analysis/InstructionSimplify.cpp lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200911100108.nAA18pl1009326@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 19:08:51 2009 New Revision: 86637 URL: http://llvm.org/viewvc/llvm-project?rev=86637&view=rev Log: add a new SimplifyInstruction API, which is like ConstantFoldInstruction, except that the result may not be a constant. Switch jump threading to use it so that it gets things like (X & 0) -> 0, which occur when phi preds are deleted and the remaining phi pred was a zero. Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionSimplify.h?rev=86637&r1=86636&r2=86637&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h (original) +++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Mon Nov 9 19:08:51 2009 @@ -17,10 +17,10 @@ #define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H namespace llvm { + class Instruction; class Value; class TargetData; - /// SimplifyAndInst - Given operands for an And, see if we can /// fold the result. If not, this returns null. Value *SimplifyAndInst(Value *LHS, Value *RHS, @@ -55,6 +55,10 @@ Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const TargetData *TD = 0); + /// SimplifyInstruction - See if we can compute a simplified version of this + /// instruction. If not, this returns null. + Value *SimplifyInstruction(Instruction *I, const TargetData *TD = 0); + } // end namespace llvm #endif Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=86637&r1=86636&r2=86637&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Mon Nov 9 19:08:51 2009 @@ -291,3 +291,23 @@ return SimplifyFCmpInst(Predicate, LHS, RHS, TD); } + +/// SimplifyInstruction - See if we can compute a simplified version of this +/// instruction. If not, this returns null. +Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD) { + switch (I->getOpcode()) { + default: + return ConstantFoldInstruction(I, TD); + case Instruction::And: + return SimplifyAndInst(I->getOperand(0), I->getOperand(1), TD); + case Instruction::Or: + return SimplifyOrInst(I->getOperand(0), I->getOperand(1), TD); + case Instruction::ICmp: + return SimplifyICmpInst(cast(I)->getPredicate(), + I->getOperand(0), I->getOperand(1), TD); + case Instruction::FCmp: + return SimplifyFCmpInst(cast(I)->getPredicate(), + I->getOperand(0), I->getOperand(1), TD); + } +} + Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86637&r1=86636&r2=86637&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Mon Nov 9 19:08:51 2009 @@ -16,7 +16,6 @@ #include "llvm/IntrinsicInst.h" #include "llvm/LLVMContext.h" #include "llvm/Pass.h" -#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" @@ -223,9 +222,9 @@ Instruction *User = cast(U.getUser()); U = PNV; - // See if we can simplify it (constant folding). - if (Constant *C = ConstantFoldInstruction(User, TD)) { - User->replaceAllUsesWith(C); + // See if we can simplify it. + if (Value *V = SimplifyInstruction(User, TD)) { + User->replaceAllUsesWith(V); User->eraseFromParent(); } } @@ -1203,8 +1202,8 @@ BI = NewBB->begin(); for (BasicBlock::iterator E = NewBB->end(); BI != E; ) { Instruction *Inst = BI++; - if (Constant *C = ConstantFoldInstruction(Inst, TD)) { - Inst->replaceAllUsesWith(C); + if (Value *V = SimplifyInstruction(Inst, TD)) { + Inst->replaceAllUsesWith(V); Inst->eraseFromParent(); continue; } From sabre at nondot.org Mon Nov 9 19:19:06 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 01:19:06 -0000 Subject: [llvm-commits] [llvm] r86639 - /llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200911100119.nAA1J6Ru009661@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 19:19:06 2009 New Revision: 86639 URL: http://llvm.org/viewvc/llvm-project?rev=86639&view=rev Log: don't invalidate PN, rewrite of this code is in progress anyway. Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86639&r1=86638&r2=86639&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Mon Nov 9 19:19:06 2009 @@ -223,10 +223,11 @@ U = PNV; // See if we can simplify it. - if (Value *V = SimplifyInstruction(User, TD)) { - User->replaceAllUsesWith(V); - User->eraseFromParent(); - } + if (User != PN) + if (Value *V = SimplifyInstruction(User, TD)) { + User->replaceAllUsesWith(V); + User->eraseFromParent(); + } } PN->replaceAllUsesWith(PNV); From gohman at apple.com Mon Nov 9 19:33:08 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 10 Nov 2009 01:33:08 -0000 Subject: [llvm-commits] [llvm] r86640 - /llvm/trunk/test/Transforms/LCSSA/indirectbr.ll Message-ID: <200911100133.nAA1X90K010143@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 19:33:08 2009 New Revision: 86640 URL: http://llvm.org/viewvc/llvm-project?rev=86640&view=rev Log: Trim a bunch of unneeded code from this testcase. Modified: llvm/trunk/test/Transforms/LCSSA/indirectbr.ll Modified: llvm/trunk/test/Transforms/LCSSA/indirectbr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LCSSA/indirectbr.ll?rev=86640&r1=86639&r2=86640&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LCSSA/indirectbr.ll (original) +++ llvm/trunk/test/Transforms/LCSSA/indirectbr.ll Mon Nov 9 19:33:08 2009 @@ -35,7 +35,7 @@ "23": ; preds = %"1375", %"22" %0 = phi i32 [ undef, %"22" ], [ %1, %"1375" ] ; [#uses=1] - indirectbr i8* undef, [label %"15", label %"24", label %"25", label %"26", label %"27", label %"28", label %"29", label %"30", label %"32", label %"32", label %"33", label %"35", label %"36", label %"41", label %"41", label %"60", label %"61", label %"65", label %"76", label %"87", label %"95", label %"103", label %"104", label %"108", label %"119", label %"130", label %"138", label %"146", label %"164", label %"162", label %"163", label %"166", label %"167", label %"173", label %"173", label %"173", label %"173", label %"173", label %"192", label %"193", label %"194", label %"196", label %"206", label %"231", label %"241", label %"251", label %"261", label %"307", label %"353", label %"354", label %"355", label %"361", label %"367", label %"400", label %"433", label %"466", label %"499", label %"509", label %"519", label %"529", label %"571", label %"589", label %"607", label %"635", label %"655", label %"664", label %"671", label %"680", label %"687", label %"692", labe! l %"698", label %"704", label %"715", label %"715", label %"716", label %"725", label %"725", label %"725", label %"725", label %"724", label %"724", label %"724", label %"724", label %"737", label %"737", label %"737", label %"737", label %"761", label %"758", label %"759", label %"760", label %"766", label %"763", label %"764", label %"765", label %"771", label %"768", label %"769", label %"770", label %"780", label %"777", label %"778", label %"779", label %"821", label %"826", label %"831", label %"832", label %"833", label %"836", label %"836", label %"886", label %"905", label %"978", label %"978", label %"1136", label %"1166", label %"1179", label %"1201", label %"1212", label %"1212", label %"1274", label %"1284", label %"1284", label %"1346", label %"1347", label %"1348", label %"1349", label %"1350", label %"1353", label %"1353", label %"1353", label %"1355", label %"1355", label %"1357", label %"1357", label %"1358", label %"1359", label %"1374", label %"1375", l! abel %"1376", label %"1377", label %"1378", label %"1379", lab! el %"138 6", label %"1395", label %"1394", label %"1425", label %"1426", label %"1440", label %"1449", label %"1455", label %"1461", label %"1471", label %"1482", label %"1484", label %"1486", label %"1489", label %"1489", label %"1492", label %"1494", label %"1494", label %"1497", label %"1499", label %"1499", label %"1515", label %"1546", label %"1546", label %"1566", label %"1584", label %"1587", label %"1591", label %"1605", label %"1609", label %"1609", label %"1640", label %"1648", label %"1651", label %"1703", label %"1710", label %"1718", label %"1724", label %"1725", label %"1726", label %"1727", label %"1728", label %"1731", label %"1732", label %"1733", label %"1734", label %"1735", label %"1741", label %"1750", label %"1752", label %"1754", label %"1755", label %"1757", label %"1759", label %"1761", label %"1764", label %"1764", label %"1766", label %"1768", label %"1775", label %"1775", label %"1781", label %"1781", label %"1790", label %"1791", label %"1801", label %"18! 02", label %"1803", label %"1805", label %"1807", label %"1809", label %"1817", label %"1819", label %"1821", label %"1823", label %"1825", label %"1827", label %"1836", label %"1836", label %"1845", label %"1845", label %"1848", label %"1849", label %"1851", label %"1853", label %"1856", label %"1861", label %"1861"] + indirectbr i8* undef, [label %"15", label %"24", label %"25", label %"26", label %"27", label %"28", label %"29", label %"30", label %"32", label %"32", label %"33", label %"167", label %"173", label %"173", label %"173", label %"173", label %"173", label %"192", label %"193", label %"194", label %"196", label %"206", label %"231", label %"241", label %"251", label %"261", label %"307", label %"353", label %"354", label %"355", label %"361", label %"367", label %"400", label %"433", label %"466", label %"499", label %"509", label %"519", label %"529", label %"571", label %"589", label %"607", label %"635", label %"655", label %"664", label %"671", label %"680", label %"687", label %"692", label %"698", label %"704", label %"715", label %"715", label %"716", label %"725", label %"725", label %"725", label %"725", label %"724", label %"724", label %"724", label %"724", label %"737", label %"737", label %"737", label %"737", label %"761", label %"758", label %"759", label %"! 760", label %"766", label %"763", label %"764", label %"765", label %"771", label %"768", label %"769", label %"770", label %"780", label %"777", label %"778", label %"779", label %"821", label %"826", label %"831", label %"832", label %"833", label %"836", label %"836", label %"886", label %"905", label %"978", label %"978", label %"1136", label %"1166", label %"1179", label %"1201", label %"1212", label %"1212", label %"1274", label %"1284", label %"1284", label %"1346", label %"1347", label %"1348", label %"1349", label %"1350", label %"1353", label %"1353", label %"1353", label %"1355", label %"1355", label %"1357", label %"1357", label %"1358", label %"1359", label %"1374", label %"1375", label %"1376", label %"1377", label %"1378", label %"1379", label %"1386", label %"1395", label %"1394", label %"1425", label %"1426", label %"1440", label %"1449", label %"1455", label %"1461", label %"1471", label %"1482", label %"1484", label %"1486", label %"1489", label %"1489", ! label %"1492", label %"1494", label %"1494", label %"1497", la! bel %"14 99", label %"1499", label %"1515", label %"1546", label %"1546", label %"1566", label %"1584", label %"1587", label %"1591", label %"1605", label %"1609", label %"1609", label %"1640", label %"1648", label %"1651", label %"1703", label %"1710", label %"1718", label %"1724", label %"1725", label %"1726", label %"1727", label %"1728", label %"1731", label %"1732", label %"1733", label %"1734", label %"1735", label %"1741", label %"1750", label %"1752", label %"1754", label %"1755", label %"1757", label %"1759", label %"1761", label %"1764", label %"1764", label %"1766", label %"1768", label %"1775", label %"1775", label %"1781", label %"1781", label %"1790", label %"1827", label %"1836", label %"1836", label %"1845", label %"1845", label %"1848", label %"1849", label %"1851", label %"1853", label %"1856", label %"1861", label %"1861"] "24": ; preds = %"23" unreachable @@ -64,63 +64,6 @@ "33": ; preds = %"23" unreachable -"35": ; preds = %"23" - unreachable - -"36": ; preds = %"23" - unreachable - -"60": ; preds = %"23" - unreachable - -"61": ; preds = %"23" - unreachable - -"65": ; preds = %"23" - unreachable - -"76": ; preds = %"23" - unreachable - -"87": ; preds = %"23" - unreachable - -"95": ; preds = %"23" - unreachable - -"103": ; preds = %"23" - unreachable - -"104": ; preds = %"23" - unreachable - -"108": ; preds = %"23" - unreachable - -"119": ; preds = %"23" - unreachable - -"130": ; preds = %"23" - unreachable - -"138": ; preds = %"23" - unreachable - -"146": ; preds = %"23" - unreachable - -"162": ; preds = %"23" - unreachable - -"163": ; preds = %"23" - unreachable - -"164": ; preds = %"23" - unreachable - -"166": ; preds = %"23" - unreachable - "167": ; preds = %"23" unreachable @@ -564,42 +507,6 @@ "1790": ; preds = %"23" unreachable -"1791": ; preds = %"23" - unreachable - -"1801": ; preds = %"23" - unreachable - -"1802": ; preds = %"23" - unreachable - -"1803": ; preds = %"23" - unreachable - -"1805": ; preds = %"23" - unreachable - -"1807": ; preds = %"23" - unreachable - -"1809": ; preds = %"23" - unreachable - -"1817": ; preds = %"23" - unreachable - -"1819": ; preds = %"23" - unreachable - -"1821": ; preds = %"23" - unreachable - -"1823": ; preds = %"23" - unreachable - -"1825": ; preds = %"23" - unreachable - "1827": ; preds = %"23" unreachable From gohman at apple.com Mon Nov 9 19:36:20 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 10 Nov 2009 01:36:20 -0000 Subject: [llvm-commits] [llvm] r86641 - /llvm/trunk/lib/CodeGen/BranchFolding.cpp Message-ID: <200911100136.nAA1aK57010254@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 19:36:20 2009 New Revision: 86641 URL: http://llvm.org/viewvc/llvm-project?rev=86641&view=rev Log: Minor code simplification. Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=86641&r1=86640&r2=86641&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Mon Nov 9 19:36:20 2009 @@ -600,7 +600,7 @@ // Walk through equivalence sets looking for actual exact matches. while (MergePotentials.size() > 1) { - unsigned CurHash = prior(MergePotentials.end())->first; + unsigned CurHash = MergePotentials.back().first; // Build SameTails, identifying the set of blocks with this hash code // and with the maximum number of instructions in common. From gohman at apple.com Mon Nov 9 19:37:58 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 10 Nov 2009 01:37:58 -0000 Subject: [llvm-commits] [llvm] r86642 - /llvm/trunk/lib/CodeGen/BranchFolding.cpp Message-ID: <200911100137.nAA1bwXc010311@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 9 19:37:57 2009 New Revision: 86642 URL: http://llvm.org/viewvc/llvm-project?rev=86642&view=rev Log: Remove an unused variable. Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=86642&r1=86641&r2=86642&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Mon Nov 9 19:37:57 2009 @@ -1179,7 +1179,6 @@ // Analyze the branch at the end of the block before the succ. MachineBasicBlock *SuccBB = *SI; MachineFunction::iterator SuccPrev = SuccBB; --SuccPrev; - std::vector SuccPrevCond; // If this block doesn't already fall-through to that successor, and if // the succ doesn't already have a block that can fall through into it, From ofv at wanadoo.es Mon Nov 9 19:45:05 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 10 Nov 2009 01:45:05 -0000 Subject: [llvm-commits] [llvm] r86644 - /llvm/trunk/cmake/config-ix.cmake Message-ID: <200911100145.nAA1j5O6010608@zion.cs.uiuc.edu> Author: ofv Date: Mon Nov 9 19:45:05 2009 New Revision: 86644 URL: http://llvm.org/viewvc/llvm-project?rev=86644&view=rev Log: CMake: Remove unnecessary `unset' which was not supported by old cmake releases. Modified: llvm/trunk/cmake/config-ix.cmake Modified: llvm/trunk/cmake/config-ix.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=86644&r1=86643&r2=86644&view=diff ============================================================================== --- llvm/trunk/cmake/config-ix.cmake (original) +++ llvm/trunk/cmake/config-ix.cmake Mon Nov 9 19:45:05 2009 @@ -136,7 +136,6 @@ mark_as_advanced(HAVE_${NAME}) else(LLVM_PATH_${NAME}) set(HAVE_${NAME} "" CACHE INTERNAL "Is ${name} available ?") - unset(LLVM_PATH_${NAME} CACHE) endif(LLVM_PATH_${NAME}) endfunction() From johnny.chen at apple.com Mon Nov 9 19:46:22 2009 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 9 Nov 2009 17:46:22 -0800 Subject: [llvm-commits] Question on emitLoadStoreInstruction() of ARMCodeEmitter.cpp Message-ID: <7A82351B-4D89-4F9A-A90F-D546B6F28832@apple.com> Hi, I have a question wrt the following fragment of code: // Operand 0 of a pre- and post-indexed store is the address base // writeback. Skip it. bool Skipped = false; if (IsPrePost && Form == ARMII::StFrm) { ++OpIdx; Skipped = true; } // Set first operand if (ImplicitRd) // Special handling for implicit use (e.g. PC). Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd) << ARMII::RegRdShift); else Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift; and from the Record definition of LDRB_POST: def LDRB_POST { // Instruction InstARM I AI2ldbpo field bits<32> Inst = { ?, ?, ?, ?, 0, 1, ?, 0, ?, 1, 0, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? }; string Namespace = "ARM"; dag OutOperandList = (outs GPR:$dst, GPR:$base_wb); dag InOperandList = (ins GPR:$base, am2offset:$offset, pred:$p); string AsmString = "ldrb${p} $dst, [$base], $offset"; it looks like the processing of "address base writeback" should happen after the processing of RegRd, if the ordering of OutOperandList followed by InOperandList is to be observed. Is my understanding of the ordering of the MachineOperands correct? If this is the case, then there could be some bug in the codegen which compensates for the incorrect ordering/processing of base_writeback/dst? Thanks. From ofv at wanadoo.es Mon Nov 9 19:47:24 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 10 Nov 2009 02:47:24 +0100 Subject: [llvm-commits] [llvm] r86547 - in /llvm/trunk: cmake/config-ix.cmake include/llvm/Config/config.h.cmake In-Reply-To: <05076F8D-8E99-4BCD-BDA0-AB1F2FD5DA05@apple.com> (Mike Stump's message of "Mon, 9 Nov 2009 15:48:01 -0800") References: <200911091526.nA9FQhRr016776@zion.cs.uiuc.edu> <05076F8D-8E99-4BCD-BDA0-AB1F2FD5DA05@apple.com> Message-ID: <87r5s76thv.fsf@telefonica.net> Mike Stump writes: > I get: > > -- Performing Test HAVE_U_INT64_T - Success > CMake Error at cmake/config-ix.cmake:139 (unset): > Unknown CMake command "unset". > Call Stack (most recent call first): > cmake/config-ix.cmake:143 (llvm_find_program) > CMakeLists.txt:161 (include) > > > -- Configuring incomplete, errors occurred! > > ? I'm using cmake version 2.6-patch 2. Thanks. unset was introduced by -patch4, IIRC. As it seems that it is not strictly required, I removed it. -- ?scar From sabre at nondot.org Mon Nov 9 19:56:04 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 01:56:04 -0000 Subject: [llvm-commits] [llvm] r86645 - /llvm/trunk/lib/Analysis/InstructionSimplify.cpp Message-ID: <200911100156.nAA1u4Rd011110@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 19:56:04 2009 New Revision: 86645 URL: http://llvm.org/viewvc/llvm-project?rev=86645&view=rev Log: remove some redundant parens. Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=86645&r1=86644&r2=86645&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Mon Nov 9 19:56:04 2009 @@ -63,8 +63,8 @@ // A & ~A = ~A & A = 0 Value *A, *B; - if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || - (match(Op1, m_Not(m_Value(A))) && A == Op0)) + if (match(Op0, m_Not(m_Value(A)) && A == Op1) || + match(Op1, m_Not(m_Value(A)) && A == Op0)) return Constant::getNullValue(Op0->getType()); // (A | ?) & A = A @@ -123,8 +123,8 @@ // A | ~A = ~A | A = -1 Value *A, *B; - if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || - (match(Op1, m_Not(m_Value(A))) && A == Op0)) + if (match(Op0, m_Not(m_Value(A)) && A == Op1) || + match(Op1, m_Not(m_Value(A)) && A == Op0)) return Constant::getAllOnesValue(Op0->getType()); // (A & ?) | A = A From sabre at nondot.org Mon Nov 9 19:57:32 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 01:57:32 -0000 Subject: [llvm-commits] [llvm] r86646 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/basic.ll Message-ID: <200911100157.nAA1vWM3011198@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 19:57:31 2009 New Revision: 86646 URL: http://llvm.org/viewvc/llvm-project?rev=86646&view=rev Log: make jump threading recursively simplify expressions instead of doing it just one level deep. On the testcase we go from getting this: F1: ; preds = %T2 %F = and i1 true, %cond ; [#uses=1] br i1 %F, label %X, label %Y to a fully threaded: F1: ; preds = %T2 br label %Y This changes gets us to the point where we're forming (too many) switch instructions on doug's strswitch testcase. Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp llvm/trunk/test/Transforms/JumpThreading/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86646&r1=86645&r2=86646&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Mon Nov 9 19:57:31 2009 @@ -182,6 +182,40 @@ //===----------------------------------------------------------------------===// +/// ReplaceAndSimplifyAllUses - Perform From->replaceAllUsesWith(To) and then +/// delete the From instruction. In addition to a basic RAUW, this does a +/// recursive simplification of the newly formed instructions. This catches +/// things where one simplification exposes other opportunities. This only +/// simplifies and deletes scalar operations, it does not change the CFG. +/// +static void ReplaceAndSimplifyAllUses(Instruction *From, Value *To, + const TargetData *TD) { + assert(From != To && "ReplaceAndSimplifyAllUses(X,X) is not valid!"); + + // FromHandle - This keeps a weakvh on the from value so that we can know if + // it gets deleted out from under us in a recursive simplification. + WeakVH FromHandle(From); + + while (!From->use_empty()) { + // Update the instruction to use the new value. + Use &U = From->use_begin().getUse(); + Instruction *User = cast(U.getUser()); + U = To; + + // See if we can simplify it. + if (Value *V = SimplifyInstruction(User, TD)) { + // Recursively simplify this. + ReplaceAndSimplifyAllUses(User, V, TD); + + // If the recursive simplification ended up revisiting and deleting 'From' + // then we're done. + if (FromHandle == 0) + return; + } + } + From->eraseFromParent(); +} + /// RemovePredecessorAndSimplify - Like BasicBlock::removePredecessor, this /// method is called when we're about to delete Pred as a predecessor of BB. If @@ -212,26 +246,11 @@ Value *PNV = PN->hasConstantValue(); if (PNV == 0) continue; + // If we're able to simplify the phi to a single value, substitute the new + // value into all of its uses. assert(PNV != PN && "hasConstantValue broken"); - // If we're able to simplify the phi to a constant, simplify it into its - // uses. - while (!PN->use_empty()) { - // Update the instruction to use the new value. - Use &U = PN->use_begin().getUse(); - Instruction *User = cast(U.getUser()); - U = PNV; - - // See if we can simplify it. - if (User != PN) - if (Value *V = SimplifyInstruction(User, TD)) { - User->replaceAllUsesWith(V); - User->eraseFromParent(); - } - } - - PN->replaceAllUsesWith(PNV); - PN->eraseFromParent(); + ReplaceAndSimplifyAllUses(PN, PNV, TD); // If recursive simplification ended up deleting the next PHI node we would // iterate to, then our iterator is invalid, restart scanning from the top @@ -1203,9 +1222,12 @@ BI = NewBB->begin(); for (BasicBlock::iterator E = NewBB->end(); BI != E; ) { Instruction *Inst = BI++; + if (Value *V = SimplifyInstruction(Inst, TD)) { - Inst->replaceAllUsesWith(V); - Inst->eraseFromParent(); + WeakVH BIHandle(BI); + ReplaceAndSimplifyAllUses(Inst, V, TD); + if (BIHandle == 0) + BI = NewBB->begin(); continue; } Modified: llvm/trunk/test/Transforms/JumpThreading/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/basic.ll?rev=86646&r1=86645&r2=86646&view=diff ============================================================================== --- llvm/trunk/test/Transforms/JumpThreading/basic.ll (original) +++ llvm/trunk/test/Transforms/JumpThreading/basic.ll Mon Nov 9 19:57:31 2009 @@ -203,3 +203,35 @@ ; CHECK-NEXT: phi i32 } + +declare i1 @test8a() + +define i32 @test8b(i1 %cond, i1 %cond2) { +; CHECK: @test8b +T0: + %A = call i1 @test8a() + br i1 %A, label %T1, label %F1 +T1: + %B = call i1 @test8a() + br i1 %B, label %T2, label %F1 +T2: + %C = call i1 @test8a() + br i1 %cond, label %T3, label %F1 +T3: + ret i32 0 + +F1: +; TODO: F1 uncond branch block should be removed, T2 should jump directly to Y. +; CHECK: F1: +; CHECK-NEXT br label %Y + %D = phi i32 [0, %T0], [0, %T1], [1, %T2] + %E = icmp eq i32 %D, 1 + %F = and i1 %E, %cond + br i1 %F, label %X, label %Y +X: + call i1 @test8a() + ret i32 1 +Y: + ret i32 2 +} + From sabre at nondot.org Mon Nov 9 20:04:54 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 02:04:54 -0000 Subject: [llvm-commits] [llvm] r86648 - /llvm/trunk/lib/Analysis/InstructionSimplify.cpp Message-ID: <200911100204.nAA24svG011529@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 20:04:54 2009 New Revision: 86648 URL: http://llvm.org/viewvc/llvm-project?rev=86648&view=rev Log: I misread the parens, not so redundant after all. Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=86648&r1=86647&r2=86648&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Mon Nov 9 20:04:54 2009 @@ -63,8 +63,8 @@ // A & ~A = ~A & A = 0 Value *A, *B; - if (match(Op0, m_Not(m_Value(A)) && A == Op1) || - match(Op1, m_Not(m_Value(A)) && A == Op0)) + if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || + (match(Op1, m_Not(m_Value(A))) && A == Op0)) return Constant::getNullValue(Op0->getType()); // (A | ?) & A = A @@ -123,8 +123,8 @@ // A | ~A = ~A | A = -1 Value *A, *B; - if (match(Op0, m_Not(m_Value(A)) && A == Op1) || - match(Op1, m_Not(m_Value(A)) && A == Op0)) + if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || + (match(Op1, m_Not(m_Value(A))) && A == Op0)) return Constant::getAllOnesValue(Op0->getType()); // (A & ?) | A = A From bruno.cardoso at gmail.com Mon Nov 9 20:35:14 2009 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Tue, 10 Nov 2009 02:35:14 -0000 Subject: [llvm-commits] [llvm] r86651 - /llvm/trunk/lib/Target/Mips/MipsInstrFPU.td Message-ID: <200911100235.nAA2ZERO012563@zion.cs.uiuc.edu> Author: bruno Date: Mon Nov 9 20:35:13 2009 New Revision: 86651 URL: http://llvm.org/viewvc/llvm-project?rev=86651&view=rev Log: Fix PR5445 Modified: llvm/trunk/lib/Target/Mips/MipsInstrFPU.td Modified: llvm/trunk/lib/Target/Mips/MipsInstrFPU.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrFPU.td?rev=86651&r1=86650&r2=86651&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrFPU.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrFPU.td Mon Nov 9 20:35:13 2009 @@ -281,7 +281,7 @@ // Floating Point Patterns //===----------------------------------------------------------------------===// def fpimm0 : PatLeaf<(fpimm), [{ - return N->isExactlyValue(+0.0); + return N->isExactlyValue(+0.0) || N->isExactlyValue(-0.0); }]>; def : Pat<(f32 fpimm0), (MTC1 ZERO)>; From daniel at zuster.org Mon Nov 9 20:40:21 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 10 Nov 2009 02:40:21 -0000 Subject: [llvm-commits] [llvm] r86653 - /llvm/trunk/utils/lit/lit.py Message-ID: <200911100240.nAA2eLS5012769@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Nov 9 20:40:21 2009 New Revision: 86653 URL: http://llvm.org/viewvc/llvm-project?rev=86653&view=rev Log: lit: Fix bug in --show-suites which accidentally override the list of tests. Modified: llvm/trunk/utils/lit/lit.py Modified: llvm/trunk/utils/lit/lit.py URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit.py?rev=86653&r1=86652&r2=86653&view=diff ============================================================================== --- llvm/trunk/utils/lit/lit.py (original) +++ llvm/trunk/utils/lit/lit.py Mon Nov 9 20:40:21 2009 @@ -452,8 +452,8 @@ print '-- Test Suites --' suitesAndTests = suitesAndTests.items() suitesAndTests.sort(key = lambda (ts,_): ts.name) - for ts,tests in suitesAndTests: - print ' %s - %d tests' %(ts.name, len(tests)) + for ts,ts_tests in suitesAndTests: + print ' %s - %d tests' %(ts.name, len(ts_tests)) print ' Source Root: %s' % ts.source_root print ' Exec Root : %s' % ts.exec_root From daniel at zuster.org Mon Nov 9 20:41:18 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 10 Nov 2009 02:41:18 -0000 Subject: [llvm-commits] [llvm] r86654 - in /llvm/trunk/utils/lit: ExampleTests.ObjDir/ ExampleTests/ ExampleTests/Clang/ ExampleTests/LLVM.InTree/ ExampleTests/LLVM.InTree/test/ ExampleTests/LLVM.InTree/test/Bar/ ExampleTests/LLVM.OutOfTree/ ExampleTests/LLVM.OutOfTree/obj/ ExampleTests/LLVM.OutOfTree/obj/test/ ExampleTests/LLVM.OutOfTree/obj/test/Foo/ ExampleTests/LLVM.OutOfTree/src/ ExampleTests/LLVM.OutOfTree/src/test/ ExampleTests/LLVM.OutOfTree/src/test/Foo/ ExampleTests/ShExternal/ ExampleTests/ShInternal/ ExampleTests/Tc... Message-ID: <200911100241.nAA2fJLX012863@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Nov 9 20:41:17 2009 New Revision: 86654 URL: http://llvm.org/viewvc/llvm-project?rev=86654&view=rev Log: lit: Add ExampleTests, for testing lit and demonstrating test suite features. Added: llvm/trunk/utils/lit/ExampleTests/ llvm/trunk/utils/lit/ExampleTests.ObjDir/ llvm/trunk/utils/lit/ExampleTests.ObjDir/lit.site.cfg llvm/trunk/utils/lit/ExampleTests/Clang/ llvm/trunk/utils/lit/ExampleTests/Clang/fsyntax-only.c llvm/trunk/utils/lit/ExampleTests/Clang/lit.cfg llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/ llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/ llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/Bar/ llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/Bar/bar-test.ll llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/Bar/dg.exp llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/lit.cfg llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/lit.site.cfg llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/site.exp llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/lit.local.cfg llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/Foo/ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/Foo/lit.local.cfg llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/lit.site.cfg llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/data.txt llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/dg.exp llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/pct-S.ll llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/lit.cfg llvm/trunk/utils/lit/ExampleTests/ShExternal/ llvm/trunk/utils/lit/ExampleTests/ShExternal/lit.local.cfg llvm/trunk/utils/lit/ExampleTests/ShInternal/ llvm/trunk/utils/lit/ExampleTests/ShInternal/lit.local.cfg llvm/trunk/utils/lit/ExampleTests/TclTest/ llvm/trunk/utils/lit/ExampleTests/TclTest/lit.local.cfg llvm/trunk/utils/lit/ExampleTests/TclTest/stderr-pipe.ll llvm/trunk/utils/lit/ExampleTests/TclTest/tcl-redir-1.ll llvm/trunk/utils/lit/ExampleTests/fail.c llvm/trunk/utils/lit/ExampleTests/lit.cfg llvm/trunk/utils/lit/ExampleTests/pass.c llvm/trunk/utils/lit/ExampleTests/xfail.c llvm/trunk/utils/lit/ExampleTests/xpass.c Added: llvm/trunk/utils/lit/ExampleTests.ObjDir/lit.site.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests.ObjDir/lit.site.cfg?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests.ObjDir/lit.site.cfg (added) +++ llvm/trunk/utils/lit/ExampleTests.ObjDir/lit.site.cfg Mon Nov 9 20:41:17 2009 @@ -0,0 +1,15 @@ +# -*- Python -*- + +# Site specific configuration file. +# +# Typically this will be generated by the build system to automatically set +# certain configuration variables which cannot be autodetected, so that 'lit' +# can easily be used on the command line. + +import os + +# Preserve the obj_root, for use by the main lit.cfg. +config.example_obj_root = os.path.dirname(__file__) + +lit.load_config(config, os.path.join(config.test_source_root, + 'lit.cfg')) Added: llvm/trunk/utils/lit/ExampleTests/Clang/fsyntax-only.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/Clang/fsyntax-only.c?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/Clang/fsyntax-only.c (added) +++ llvm/trunk/utils/lit/ExampleTests/Clang/fsyntax-only.c Mon Nov 9 20:41:17 2009 @@ -0,0 +1,4 @@ +// RUN: clang -fsyntax-only -Xclang -verify %s + +int f0(void) {} // expected-warning {{control reaches end of non-void function}} + Added: llvm/trunk/utils/lit/ExampleTests/Clang/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/Clang/lit.cfg?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/Clang/lit.cfg (added) +++ llvm/trunk/utils/lit/ExampleTests/Clang/lit.cfg Mon Nov 9 20:41:17 2009 @@ -0,0 +1,80 @@ +# -*- Python -*- + +# Configuration file for the 'lit' test runner. + +# name: The name of this test suite. +config.name = 'Clang' + +# testFormat: The test format to use to interpret tests. +# +# For now we require '&&' between commands, until they get globally killed and +# the test runner updated. +config.test_format = lit.formats.ShTest(execute_external = True) + +# suffixes: A list of file extensions to treat as test files. +config.suffixes = ['.c', '.cpp', '.m', '.mm'] + +# target_triple: Used by ShTest and TclTest formats for XFAIL checks. +config.target_triple = 'foo' + +### + +# Discover the 'clang' and 'clangcc' to use. + +import os + +def inferClang(PATH): + # Determine which clang to use. + clang = os.getenv('CLANG') + + # If the user set clang in the environment, definitely use that and don't + # try to validate. + if clang: + return clang + + # Otherwise look in the path. + clang = lit.util.which('clang', PATH) + + if not clang: + lit.fatal("couldn't find 'clang' program, try setting " + "CLANG in your environment") + + return clang + +def inferClangCC(clang, PATH): + clangcc = os.getenv('CLANGCC') + + # If the user set clang in the environment, definitely use that and don't + # try to validate. + if clangcc: + return clangcc + + # Otherwise try adding -cc since we expect to be looking in a build + # directory. + if clang.endswith('.exe'): + clangccName = clang[:-4] + '-cc.exe' + else: + clangccName = clang + '-cc' + clangcc = lit.util.which(clangccName, PATH) + if not clangcc: + # Otherwise ask clang. + res = lit.util.capture([clang, '-print-prog-name=clang-cc']) + res = res.strip() + if res and os.path.exists(res): + clangcc = res + + if not clangcc: + lit.fatal("couldn't find 'clang-cc' program, try setting " + "CLANGCC in your environment") + + return clangcc + +clang = inferClang(config.environment['PATH']) +if not lit.quiet: + lit.note('using clang: %r' % clang) +config.substitutions.append( (' clang ', ' ' + clang + ' ') ) + +clang_cc = inferClangCC(clang, config.environment['PATH']) +if not lit.quiet: + lit.note('using clang-cc: %r' % clang_cc) +config.substitutions.append( (' clang-cc ', ' ' + clang_cc + ' ') ) Added: llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/Bar/bar-test.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/Bar/bar-test.ll?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/Bar/bar-test.ll (added) +++ llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/Bar/bar-test.ll Mon Nov 9 20:41:17 2009 @@ -0,0 +1,3 @@ +; RUN: true +; XFAIL: * +; XTARGET: darwin Added: llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/Bar/dg.exp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/Bar/dg.exp?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/Bar/dg.exp (added) +++ llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/Bar/dg.exp Mon Nov 9 20:41:17 2009 @@ -0,0 +1,6 @@ +load_lib llvm.exp + +if { [llvm_supports_target X86] } { + RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]] +} + Added: llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/lit.cfg?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/lit.cfg (added) +++ llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/lit.cfg Mon Nov 9 20:41:17 2009 @@ -0,0 +1,151 @@ +# -*- Python -*- + +# Configuration file for the 'lit' test runner. + +import os + +# name: The name of this test suite. +config.name = 'LLVM' + +# testFormat: The test format to use to interpret tests. +config.test_format = lit.formats.TclTest() + +# suffixes: A list of file extensions to treat as test files, this is actually +# set by on_clone(). +config.suffixes = [] + +# test_source_root: The root path where tests are located. +config.test_source_root = os.path.dirname(__file__) + +# test_exec_root: The root path where tests should be run. +llvm_obj_root = getattr(config, 'llvm_obj_root', None) +if llvm_obj_root is not None: + config.test_exec_root = os.path.join(llvm_obj_root, 'test') + +### + +import os + +# Check that the object root is known. +if config.test_exec_root is None: + # Otherwise, we haven't loaded the site specific configuration (the user is + # probably trying to run on a test file directly, and either the site + # configuration hasn't been created by the build system, or we are in an + # out-of-tree build situation). + + # Try to detect the situation where we are using an out-of-tree build by + # looking for 'llvm-config'. + # + # FIXME: I debated (i.e., wrote and threw away) adding logic to + # automagically generate the lit.site.cfg if we are in some kind of fresh + # build situation. This means knowing how to invoke the build system + # though, and I decided it was too much magic. + + llvm_config = lit.util.which('llvm-config', config.environment['PATH']) + if not llvm_config: + lit.fatal('No site specific configuration available!') + + # Get the source and object roots. + llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip() + llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip() + + # Validate that we got a tree which points to here. + this_src_root = os.path.dirname(config.test_source_root) + if os.path.realpath(llvm_src_root) != os.path.realpath(this_src_root): + lit.fatal('No site specific configuration available!') + + # Check that the site specific configuration exists. + site_cfg = os.path.join(llvm_obj_root, 'test', 'lit.site.cfg') + if not os.path.exists(site_cfg): + lit.fatal('No site specific configuration available!') + + # Okay, that worked. Notify the user of the automagic, and reconfigure. + lit.note('using out-of-tree build at %r' % llvm_obj_root) + lit.load_config(config, site_cfg) + raise SystemExit + +### + +# Load site data from DejaGNU's site.exp. +import re +site_exp = {} +# FIXME: Implement lit.site.cfg. +for line in open(os.path.join(config.llvm_obj_root, 'test', 'site.exp')): + m = re.match('set ([^ ]+) "([^"]*)"', line) + if m: + site_exp[m.group(1)] = m.group(2) + +# Add substitutions. +for sub in ['prcontext', 'llvmgcc', 'llvmgxx', 'compile_cxx', 'compile_c', + 'link', 'shlibext', 'ocamlopt', 'llvmdsymutil', 'llvmlibsdir', + 'bugpoint_topts']: + if sub in ('llvmgcc', 'llvmgxx'): + config.substitutions.append(('%' + sub, + site_exp[sub] + ' -emit-llvm -w')) + else: + config.substitutions.append(('%' + sub, site_exp[sub])) + +excludes = [] + +# Provide target_triple for use in XFAIL and XTARGET. +config.target_triple = site_exp['target_triplet'] + +# Provide llvm_supports_target for use in local configs. +targets = set(site_exp["TARGETS_TO_BUILD"].split()) +def llvm_supports_target(name): + return name in targets + +langs = set(site_exp['llvmgcc_langs'].split(',')) +def llvm_gcc_supports(name): + return name in langs + +# Provide on_clone hook for reading 'dg.exp'. +import os +simpleLibData = re.compile(r"""load_lib llvm.exp + +RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\]""", + re.MULTILINE) +conditionalLibData = re.compile(r"""load_lib llvm.exp + +if.*\[ ?(llvm[^ ]*) ([^ ]*) ?\].*{ + *RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\] +\}""", re.MULTILINE) +def on_clone(parent, cfg, for_path): + def addSuffixes(match): + if match[0] == '{' and match[-1] == '}': + cfg.suffixes = ['.' + s for s in match[1:-1].split(',')] + else: + cfg.suffixes = ['.' + match] + + libPath = os.path.join(os.path.dirname(for_path), + 'dg.exp') + if not os.path.exists(libPath): + cfg.unsupported = True + return + + # Reset unsupported, in case we inherited it. + cfg.unsupported = False + lib = open(libPath).read().strip() + + # Check for a simple library. + m = simpleLibData.match(lib) + if m: + addSuffixes(m.group(1)) + return + + # Check for a conditional test set. + m = conditionalLibData.match(lib) + if m: + funcname,arg,match = m.groups() + addSuffixes(match) + + func = globals().get(funcname) + if not func: + lit.error('unsupported predicate %r' % funcname) + elif not func(arg): + cfg.unsupported = True + return + # Otherwise, give up. + lit.error('unable to understand %r:\n%s' % (libPath, lib)) + +config.on_clone = on_clone Added: llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/lit.site.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/lit.site.cfg?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/lit.site.cfg (added) +++ llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/lit.site.cfg Mon Nov 9 20:41:17 2009 @@ -0,0 +1,10 @@ +# -*- Python -*- + +## Autogenerated by Makefile ## +# Do not edit! + +# Preserve some key paths for use by main LLVM test suite config. +config.llvm_obj_root = os.path.dirname(os.path.dirname(__file__)) + +# Let the main config do the real work. +lit.load_config(config, os.path.join(config.llvm_obj_root, 'test/lit.cfg')) Added: llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/site.exp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/site.exp?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/site.exp (added) +++ llvm/trunk/utils/lit/ExampleTests/LLVM.InTree/test/site.exp Mon Nov 9 20:41:17 2009 @@ -0,0 +1,30 @@ +## these variables are automatically generated by make ## +# Do not edit here. If you wish to override these values +# edit the last section +set target_triplet "x86_64-apple-darwin10" +set TARGETS_TO_BUILD "X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend" +set llvmgcc_langs "c,c++,objc,obj-c++" +set llvmgcc_version "4.2.1" +set prcontext "/usr/bin/tclsh8.4 /Volumes/Data/ddunbar/llvm/test/Scripts/prcontext.tcl" +set llvmtoolsdir "/Users/ddunbar/llvm.obj.64/Debug/bin" +set llvmlibsdir "/Users/ddunbar/llvm.obj.64/Debug/lib" +set srcroot "/Volumes/Data/ddunbar/llvm" +set objroot "/Volumes/Data/ddunbar/llvm.obj.64" +set srcdir "/Volumes/Data/ddunbar/llvm/test" +set objdir "/Volumes/Data/ddunbar/llvm.obj.64/test" +set gccpath "/usr/bin/gcc -arch x86_64" +set gxxpath "/usr/bin/g++ -arch x86_64" +set compile_c " /usr/bin/gcc -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -c " +set compile_cxx " /usr/bin/g++ -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -g -fno-exceptions -fno-common -Woverloaded-virtual -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -c " +set link " /usr/bin/g++ -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -g -fno-exceptions -fno-common -Woverloaded-virtual -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -g -L/Users/ddunbar/llvm.obj.64/Debug/lib -L/Volumes/Data/ddunbar/llvm.obj.64/Debug/lib " +set llvmgcc "/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc -m64 " +set llvmgxx "/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc -m64 " +set llvmgccmajvers "4" +set bugpoint_topts "-gcc-tool-args -m64" +set shlibext ".dylib" +set ocamlopt "/sw/bin/ocamlopt -cc \"g++ -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT\" -I /Users/ddunbar/llvm.obj.64/Debug/lib/ocaml" +set valgrind "" +set grep "/usr/bin/grep" +set gas "/usr/bin/as" +set llvmdsymutil "dsymutil" +## All variables above are generated by configure. Do Not Edit ## Added: llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/lit.local.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/lit.local.cfg?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/lit.local.cfg (added) +++ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/lit.local.cfg Mon Nov 9 20:41:17 2009 @@ -0,0 +1 @@ +config.excludes = ['src'] Added: llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/Foo/lit.local.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/Foo/lit.local.cfg?rev=86654&view=auto ============================================================================== (empty) Added: llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/lit.site.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/lit.site.cfg?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/lit.site.cfg (added) +++ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/lit.site.cfg Mon Nov 9 20:41:17 2009 @@ -0,0 +1,11 @@ +# -*- Python -*- + +## Autogenerated by Makefile ## +# Do not edit! + +# Preserve some key paths for use by main LLVM test suite config. +config.llvm_obj_root = os.path.dirname(os.path.dirname(__file__)) + +# Let the main config do the real work. +lit.load_config(config, os.path.join(config.llvm_obj_root, + '../src/test/lit.cfg')) Added: llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp (added) +++ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp Mon Nov 9 20:41:17 2009 @@ -0,0 +1,30 @@ +## these variables are automatically generated by make ## +# Do not edit here. If you wish to override these values +# edit the last section +set target_triplet "x86_64-apple-darwin10" +set TARGETS_TO_BUILD "X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend" +set llvmgcc_langs "c,c++,objc,obj-c++" +set llvmgcc_version "4.2.1" +set prcontext "/usr/bin/tclsh8.4 /Volumes/Data/ddunbar/llvm/test/Scripts/prcontext.tcl" +set llvmtoolsdir "/Users/ddunbar/llvm.obj.64/Debug/bin" +set llvmlibsdir "/Users/ddunbar/llvm.obj.64/Debug/lib" +set srcroot "/Volumes/Data/ddunbar/llvm" +set objroot "/Volumes/Data/ddunbar/llvm.obj.64" +set srcdir "/Volumes/Data/ddunbar/llvm/test" +set objdir "/Volumes/Data/ddunbar/llvm.obj.64/test" +set gccpath "/usr/bin/gcc -arch x86_64" +set gxxpath "/usr/bin/g++ -arch x86_64" +set compile_c " /usr/bin/gcc -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -c " +set compile_cxx " /usr/bin/g++ -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -g -fno-exceptions -fno-common -Woverloaded-virtual -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -c " +set link " /usr/bin/g++ -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -g -fno-exceptions -fno-common -Woverloaded-virtual -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -g -L/Users/ddunbar/llvm.obj.64/Debug/lib -L/Volumes/Data/ddunbar/llvm.obj.64/Debug/lib " +set llvmgcc "/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc -m64 " +set llvmgxx "/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc -m64 " +set llvmgccmajvers "4" +set bugpoint_topts "-gcc-tool-args -m64" +set shlibext ".dylib" +set ocamlopt "/sw/bin/ocamlopt -cc \"g++ -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT\" -I /Users/ddunbar/llvm.obj.64/Debug/lib/ocaml" +set valgrind "" +set grep "/usr/bin/grep" +set gas "/usr/bin/as" +set llvmdsymutil "dsymutil" +## All variables above are generated by configure. Do Not Edit ## Added: llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/data.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/data.txt?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/data.txt (added) +++ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/data.txt Mon Nov 9 20:41:17 2009 @@ -0,0 +1 @@ +hi Added: llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/dg.exp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/dg.exp?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/dg.exp (added) +++ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/dg.exp Mon Nov 9 20:41:17 2009 @@ -0,0 +1,6 @@ +load_lib llvm.exp + +if { [llvm_supports_target X86] } { + RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]] +} + Added: llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/pct-S.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/pct-S.ll?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/pct-S.ll (added) +++ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/pct-S.ll Mon Nov 9 20:41:17 2009 @@ -0,0 +1 @@ +; RUN: grep "hi" %S/data.txt \ No newline at end of file Added: llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/lit.cfg?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/lit.cfg (added) +++ llvm/trunk/utils/lit/ExampleTests/LLVM.OutOfTree/src/test/lit.cfg Mon Nov 9 20:41:17 2009 @@ -0,0 +1,151 @@ +# -*- Python -*- + +# Configuration file for the 'lit' test runner. + +import os + +# name: The name of this test suite. +config.name = 'LLVM' + +# testFormat: The test format to use to interpret tests. +config.test_format = lit.formats.TclTest() + +# suffixes: A list of file extensions to treat as test files, this is actually +# set by on_clone(). +config.suffixes = [] + +# test_source_root: The root path where tests are located. +config.test_source_root = os.path.dirname(__file__) + +# test_exec_root: The root path where tests should be run. +llvm_obj_root = getattr(config, 'llvm_obj_root', None) +if llvm_obj_root is not None: + config.test_exec_root = os.path.join(llvm_obj_root, 'test') + +### + +import os + +# Check that the object root is known. +if config.test_exec_root is None: + # Otherwise, we haven't loaded the site specific configuration (the user is + # probably trying to run on a test file directly, and either the site + # configuration hasn't been created by the build system, or we are in an + # out-of-tree build situation). + + # Try to detect the situation where we are using an out-of-tree build by + # looking for 'llvm-config'. + # + # FIXME: I debated (i.e., wrote and threw away) adding logic to + # automagically generate the lit.site.cfg if we are in some kind of fresh + # build situation. This means knowing how to invoke the build system + # though, and I decided it was too much magic. + + llvm_config = lit.util.which('llvm-config', config.environment['PATH']) + if not llvm_config: + lit.fatal('No site specific configuration available!') + + # Get the source and object roots. + llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip() + llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip() + + # Validate that we got a tree which points to here. + this_src_root = os.path.dirname(config.test_source_root) + if os.path.realpath(llvm_src_root) != os.path.realpath(this_src_root): + lit.fatal('No site specific configuration available!') + + # Check that the site specific configuration exists. + site_cfg = os.path.join(llvm_obj_root, 'test', 'lit.site.cfg') + if not os.path.exists(site_cfg): + lit.fatal('No site specific configuration available!') + + # Okay, that worked. Notify the user of the automagic, and reconfigure. + lit.note('using out-of-tree build at %r' % llvm_obj_root) + lit.load_config(config, site_cfg) + raise SystemExit + +### + +# Load site data from DejaGNU's site.exp. +import re +site_exp = {} +# FIXME: Implement lit.site.cfg. +for line in open(os.path.join(config.llvm_obj_root, 'test', 'site.exp')): + m = re.match('set ([^ ]+) "([^"]*)"', line) + if m: + site_exp[m.group(1)] = m.group(2) + +# Add substitutions. +for sub in ['prcontext', 'llvmgcc', 'llvmgxx', 'compile_cxx', 'compile_c', + 'link', 'shlibext', 'ocamlopt', 'llvmdsymutil', 'llvmlibsdir', + 'bugpoint_topts']: + if sub in ('llvmgcc', 'llvmgxx'): + config.substitutions.append(('%' + sub, + site_exp[sub] + ' -emit-llvm -w')) + else: + config.substitutions.append(('%' + sub, site_exp[sub])) + +excludes = [] + +# Provide target_triple for use in XFAIL and XTARGET. +config.target_triple = site_exp['target_triplet'] + +# Provide llvm_supports_target for use in local configs. +targets = set(site_exp["TARGETS_TO_BUILD"].split()) +def llvm_supports_target(name): + return name in targets + +langs = set(site_exp['llvmgcc_langs'].split(',')) +def llvm_gcc_supports(name): + return name in langs + +# Provide on_clone hook for reading 'dg.exp'. +import os +simpleLibData = re.compile(r"""load_lib llvm.exp + +RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\]""", + re.MULTILINE) +conditionalLibData = re.compile(r"""load_lib llvm.exp + +if.*\[ ?(llvm[^ ]*) ([^ ]*) ?\].*{ + *RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\] +\}""", re.MULTILINE) +def on_clone(parent, cfg, for_path): + def addSuffixes(match): + if match[0] == '{' and match[-1] == '}': + cfg.suffixes = ['.' + s for s in match[1:-1].split(',')] + else: + cfg.suffixes = ['.' + match] + + libPath = os.path.join(os.path.dirname(for_path), + 'dg.exp') + if not os.path.exists(libPath): + cfg.unsupported = True + return + + # Reset unsupported, in case we inherited it. + cfg.unsupported = False + lib = open(libPath).read().strip() + + # Check for a simple library. + m = simpleLibData.match(lib) + if m: + addSuffixes(m.group(1)) + return + + # Check for a conditional test set. + m = conditionalLibData.match(lib) + if m: + funcname,arg,match = m.groups() + addSuffixes(match) + + func = globals().get(funcname) + if not func: + lit.error('unsupported predicate %r' % funcname) + elif not func(arg): + cfg.unsupported = True + return + # Otherwise, give up. + lit.error('unable to understand %r:\n%s' % (libPath, lib)) + +config.on_clone = on_clone Added: llvm/trunk/utils/lit/ExampleTests/ShExternal/lit.local.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/ShExternal/lit.local.cfg?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/ShExternal/lit.local.cfg (added) +++ llvm/trunk/utils/lit/ExampleTests/ShExternal/lit.local.cfg Mon Nov 9 20:41:17 2009 @@ -0,0 +1,6 @@ +# -*- Python -*- + +config.test_format = lit.formats.ShTest(execute_external = True) + +config.suffixes = ['.c'] + Added: llvm/trunk/utils/lit/ExampleTests/ShInternal/lit.local.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/ShInternal/lit.local.cfg?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/ShInternal/lit.local.cfg (added) +++ llvm/trunk/utils/lit/ExampleTests/ShInternal/lit.local.cfg Mon Nov 9 20:41:17 2009 @@ -0,0 +1,6 @@ +# -*- Python -*- + +config.test_format = lit.formats.ShTest(execute_external = False) + +config.suffixes = ['.c'] + Added: llvm/trunk/utils/lit/ExampleTests/TclTest/lit.local.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/TclTest/lit.local.cfg?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/TclTest/lit.local.cfg (added) +++ llvm/trunk/utils/lit/ExampleTests/TclTest/lit.local.cfg Mon Nov 9 20:41:17 2009 @@ -0,0 +1,5 @@ +# -*- Python -*- + +config.test_format = lit.formats.TclTest() + +config.suffixes = ['.ll'] Added: llvm/trunk/utils/lit/ExampleTests/TclTest/stderr-pipe.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/TclTest/stderr-pipe.ll?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/TclTest/stderr-pipe.ll (added) +++ llvm/trunk/utils/lit/ExampleTests/TclTest/stderr-pipe.ll Mon Nov 9 20:41:17 2009 @@ -0,0 +1 @@ +; RUN: gcc -### > /dev/null |& grep {gcc version} Added: llvm/trunk/utils/lit/ExampleTests/TclTest/tcl-redir-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/TclTest/tcl-redir-1.ll?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/TclTest/tcl-redir-1.ll (added) +++ llvm/trunk/utils/lit/ExampleTests/TclTest/tcl-redir-1.ll Mon Nov 9 20:41:17 2009 @@ -0,0 +1,7 @@ +; RUN: echo 'hi' > %t.1 | echo 'hello' > %t.2 +; RUN: not grep 'hi' %t.1 +; RUN: grep 'hello' %t.2 + + + + Added: llvm/trunk/utils/lit/ExampleTests/fail.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/fail.c?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/fail.c (added) +++ llvm/trunk/utils/lit/ExampleTests/fail.c Mon Nov 9 20:41:17 2009 @@ -0,0 +1,2 @@ +// RUN: echo 'I am some stdout' +// RUN: false Added: llvm/trunk/utils/lit/ExampleTests/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/lit.cfg?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/lit.cfg (added) +++ llvm/trunk/utils/lit/ExampleTests/lit.cfg Mon Nov 9 20:41:17 2009 @@ -0,0 +1,23 @@ +# -*- Python -*- + +# Configuration file for the 'lit' test runner. + +# name: The name of this test suite. +config.name = 'Examples' + +# suffixes: A list of file extensions to treat as test files. +config.suffixes = ['.c', '.cpp', '.m', '.mm', '.ll'] + +# testFormat: The test format to use to interpret tests. +config.test_format = lit.formats.ShTest() + +# test_source_root: The path where tests are located (default is the test suite +# root). +config.test_source_root = None + +# test_exec_root: The path where tests are located (default is the test suite +# root). +config.test_exec_root = None + +# target_triple: Used by ShTest and TclTest formats for XFAIL checks. +config.target_triple = 'foo' Added: llvm/trunk/utils/lit/ExampleTests/pass.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/pass.c?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/pass.c (added) +++ llvm/trunk/utils/lit/ExampleTests/pass.c Mon Nov 9 20:41:17 2009 @@ -0,0 +1 @@ +// RUN: true Added: llvm/trunk/utils/lit/ExampleTests/xfail.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/xfail.c?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/xfail.c (added) +++ llvm/trunk/utils/lit/ExampleTests/xfail.c Mon Nov 9 20:41:17 2009 @@ -0,0 +1,2 @@ +// RUN: false +// XFAIL: * Added: llvm/trunk/utils/lit/ExampleTests/xpass.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/ExampleTests/xpass.c?rev=86654&view=auto ============================================================================== --- llvm/trunk/utils/lit/ExampleTests/xpass.c (added) +++ llvm/trunk/utils/lit/ExampleTests/xpass.c Mon Nov 9 20:41:17 2009 @@ -0,0 +1,2 @@ +// RUN: true +// XFAIL From daniel at zuster.org Mon Nov 9 20:41:27 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 10 Nov 2009 02:41:27 -0000 Subject: [llvm-commits] [llvm] r86655 - /llvm/trunk/docs/CommandGuide/lit.pod Message-ID: <200911100241.nAA2fRBB012879@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Nov 9 20:41:27 2009 New Revision: 86655 URL: http://llvm.org/viewvc/llvm-project?rev=86655&view=rev Log: lit: Start documentation testing architecture. Modified: llvm/trunk/docs/CommandGuide/lit.pod Modified: llvm/trunk/docs/CommandGuide/lit.pod URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/lit.pod?rev=86655&r1=86654&r2=86655&view=diff ============================================================================== --- llvm/trunk/docs/CommandGuide/lit.pod (original) +++ llvm/trunk/docs/CommandGuide/lit.pod Mon Nov 9 20:41:27 2009 @@ -36,6 +36,9 @@ the options specified on the command line, see L<"SELECTION OPTIONS"> for more information. +Users interested in the B architecture or designing a B testing +implementation should see L<"LIT ARCHITECTURE"> + =head1 GENERAL OPTIONS =over @@ -222,6 +225,119 @@ their status (generally only for failures). See the L section for more information. +=head1 LIT INFRASTRUCTURE + +This section describes the B testing architecture for users interested in +creating a new B testing implementation, or extending an existing one. + +B proper is primarily an infrastructure for discovering and running +arbitrary tests, and to expose a single convenient interface to these +tests. B itself doesn't contain know how to run tests, rather this logic is +defined by I. + +=head2 TEST SUITES + +As described in L<"TEST DISCOVERY">, tests are always located inside a I. Test suites serve to define the format of the tests they contain, the +logic for finding those tests, and any additional information to run the tests. + +B identifies test suites as directories containing I or +I files (see also B<--config-prefix>. Test suites are initially +discovered by recursively searching up the directory hierarchy for all the input +files passed on the command line. You can use B<--show-suites> to display the +discovered test suites at startup. + +Once a test suite is discovered, its config file is loaded. Config files +themselves are just Python modules which will be executed. When the config file +is executed, two important global variables are predefined: + +=over + +=item B + +The global B configuration object (a I instance), which defines +the builtin test formats, global configuration parameters, and other helper +routines for implementing test configurations. + +=item B + +This is the config object (a I instance) for the test suite, +which the config file is expected to populate. The following variables are also +available on the I object, some of which must be set by the config and +others are optional or predefined: + +B I<[required]> The name of the test suite, for use in reports and +diagnostics. + +B I<[required]> The test format object which will be used to +discover and run tests in the test suite. Generally this will be a builtin test +format available from the I module. + +B The filesystem path to the test suite root. For out-of-dir +builds this is the directory that will be scanned for tests. + +B For out-of-dir builds, the path to the test suite root inside +the object directory. This is where tests will be run and temporary output files +places. + +B A dictionary representing the environment to use when executing +tests in the suite. + +B For B test formats which scan directories for tests, this +variable as a list of suffixes to identify test files. Used by: I, +I. + +B For B test formats which substitute variables into a test +script, the list of substitutions to perform. Used by: I, I. + +B Mark an unsupported directory, all tests within it will be +reported as unsupported. Used by: I, I. + +B The parent configuration, this is the config object for the directory +containing the test suite, or None. + +B The config is actually cloned for every subdirectory inside a test +suite, to allow local configuration on a per-directory basis. The I +variable can be set to a Python function which will be called whenever a +configuration is cloned (for a subdirectory). The function should takes three +arguments: (1) the parent configuration, (2) the new configuration (which the +I function will generally modify), and (3) the test path to the new +directory being scanned. + +=back + +=head2 TEST DISCOVERY + +Once test suites are located, B recursively traverses the source directory +(following I) looking for tests. When B enters a +sub-directory, it first checks to see if a nest test suite is defined in that +directory. If so, it loads that test suite recursively, otherwise it +instantiates a local test config for the directory (see L<"LOCAL CONFIGURATION +FILES">). + +Tests are identified by the test suite they are contained within, and the +relative path inside that suite. Note that the relative path may not refer to an +actual file on disk; some test formats (such as I) define "virtual +tests" which have a path that contains both the path to the actual test file and +a subpath to identify the virtual test. + +=head2 LOCAL CONFIGURATION FILES + +When B loads a subdirectory in a test suite, it instantiates a local test +configuration by cloning the configuration for the parent direction -- the root +of this configuration chain will always be a test suite. Once the test +configuration is cloned B checks for a I file in the +subdirectory. If present, this file will be loaded and can be used to specialize +the configuration for each individual directory. This facility can be used to +define subdirectories of optional tests, or to change other configuration +parameters -- for example, to change the test format, or the suffixes which +identify test files. + +=head2 LIT EXAMPLE TESTS + +The B distribution contains several example implementations of test suites +in the I directory. + =head1 SEE ALSO L From kennethuil at gmail.com Mon Nov 9 20:42:39 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Mon, 9 Nov 2009 20:42:39 -0600 Subject: [llvm-commits] sret-demotion for large struct returns working on x86! In-Reply-To: <400d33ea0911091343w1549702enbbbb0c7b34b75cfa@mail.gmail.com> References: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> <5CC43A6B-57E4-42A7-B1E6-CCD9875F65D7@apple.com> <400d33ea0911091343w1549702enbbbb0c7b34b75cfa@mail.gmail.com> Message-ID: <400d33ea0911091842i262ebf40t5a39731c6c3de7a7@mail.gmail.com> Here's the updated version of the patch: 1. Moved the flag and demote register from MachineFunction to FunctionLoweringInfo 2. Inverted CantLowerReturn to CanLowerReturn while carrying out #1 3. Now passing the return Attributes to getReturnInfo and using its ZExt and SExt flags properly. 4. Cleaned up braces. New testcase coming as soon as I figure out how to get svn diff or mkpatch to pick up a brand-new file. -------------- next part -------------- A non-text attachment was scrubbed... Name: sret-demote.patch Type: text/x-patch Size: 16182 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091109/9bd1fa87/attachment.bin From ofv at wanadoo.es Mon Nov 9 20:45:37 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 10 Nov 2009 02:45:37 -0000 Subject: [llvm-commits] [llvm] r86656 - in /llvm/trunk: cmake/modules/AddLLVM.cmake cmake/modules/LLVMLibDeps.cmake lib/Transforms/Hello/CMakeLists.txt Message-ID: <200911100245.nAA2jbb4013035@zion.cs.uiuc.edu> Author: ofv Date: Mon Nov 9 20:45:37 2009 New Revision: 86656 URL: http://llvm.org/viewvc/llvm-project?rev=86656&view=rev Log: CMake: Support for building llvm loadable modules. Modified: llvm/trunk/cmake/modules/AddLLVM.cmake llvm/trunk/cmake/modules/LLVMLibDeps.cmake llvm/trunk/lib/Transforms/Hello/CMakeLists.txt Modified: llvm/trunk/cmake/modules/AddLLVM.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/AddLLVM.cmake?rev=86656&r1=86655&r2=86656&view=diff ============================================================================== --- llvm/trunk/cmake/modules/AddLLVM.cmake (original) +++ llvm/trunk/cmake/modules/AddLLVM.cmake Mon Nov 9 20:45:37 2009 @@ -22,6 +22,22 @@ endmacro(add_llvm_library name) +macro(add_llvm_loadable_module name) + if( NOT LLVM_ON_UNIX ) + message(STATUS "Loadable modules not supported on this platform. +${name} ignored.") + else() + set(BUILD_SHARED_LIBS ON) + llvm_process_sources( ALL_FILES ${ARGN} ) + add_library( ${name} MODULE ${ALL_FILES} ) + set_target_properties( ${name} PROPERTIES PREFIX "" ) + install(TARGETS ${name} + LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} + ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}) + endif() +endmacro(add_llvm_loadable_module name) + + macro(add_llvm_executable name) llvm_process_sources( ALL_FILES ${ARGN} ) add_executable(${name} ${ALL_FILES}) Modified: llvm/trunk/cmake/modules/LLVMLibDeps.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMLibDeps.cmake?rev=86656&r1=86655&r2=86656&view=diff ============================================================================== --- llvm/trunk/cmake/modules/LLVMLibDeps.cmake (original) +++ llvm/trunk/cmake/modules/LLVMLibDeps.cmake Mon Nov 9 20:45:37 2009 @@ -24,7 +24,6 @@ set(MSVC_LIB_DEPS_LLVMCppBackend LLVMCore LLVMCppBackendInfo LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMCppBackendInfo LLVMSupport) set(MSVC_LIB_DEPS_LLVMExecutionEngine LLVMCore LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMHello LLVMCore LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMInstrumentation LLVMAnalysis LLVMCore LLVMScalarOpts LLVMSupport LLVMSystem LLVMTransformUtils) set(MSVC_LIB_DEPS_LLVMInterpreter LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMJIT LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMMC LLVMSupport LLVMSystem LLVMTarget) Modified: llvm/trunk/lib/Transforms/Hello/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Hello/CMakeLists.txt?rev=86656&r1=86655&r2=86656&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Hello/CMakeLists.txt (original) +++ llvm/trunk/lib/Transforms/Hello/CMakeLists.txt Mon Nov 9 20:45:37 2009 @@ -1,3 +1,3 @@ -add_llvm_library( LLVMHello +add_llvm_loadable_module( LLVMHello Hello.cpp ) From baldrick at free.fr Mon Nov 9 20:49:07 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 10 Nov 2009 03:49:07 +0100 Subject: [llvm-commits] [llvm] r86603 - /llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp In-Reply-To: <200911092232.nA9MWbu6002598@zion.cs.uiuc.edu> References: <200911092232.nA9MWbu6002598@zion.cs.uiuc.edu> Message-ID: <4AF8D4A3.60409@free.fr> Hi Chris, > + // This only adjusts blocks with PHI nodes. > + if (!isa(BB->begin())) > + return; don't you still want to do BB->removePredecessor in this case? Anyway, if the BB doesn't start with a phi, the following code does essentially nothing anyway, so the test doesn't buy you much. > + //BB->removePredecessor(Pred, true); > + BB->removePredecessor(Pred, true); One of these shouldn't be there :) Also, this seems like a generally useful transform - does it really belong in JumpThreading? Ciao, Duncan. From baldrick at free.fr Mon Nov 9 20:58:24 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 10 Nov 2009 03:58:24 +0100 Subject: [llvm-commits] sret-demotion for large struct returns working on x86! In-Reply-To: <400d33ea0911091842i262ebf40t5a39731c6c3de7a7@mail.gmail.com> References: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> <5CC43A6B-57E4-42A7-B1E6-CCD9875F65D7@apple.com> <400d33ea0911091343w1549702enbbbb0c7b34b75cfa@mail.gmail.com> <400d33ea0911091842i262ebf40t5a39731c6c3de7a7@mail.gmail.com> Message-ID: <4AF8D6D0.4010108@free.fr> > New testcase coming as soon as I figure out how to get svn diff or > mkpatch to pick up a brand-new file. First do "svn add" on the new file. Ciao, Duncan. From kennethuil at gmail.com Mon Nov 9 21:06:07 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Mon, 9 Nov 2009 21:06:07 -0600 Subject: [llvm-commits] sret-demotion for large struct returns working on x86! In-Reply-To: <4AF8D6D0.4010108@free.fr> References: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> <5CC43A6B-57E4-42A7-B1E6-CCD9875F65D7@apple.com> <400d33ea0911091343w1549702enbbbb0c7b34b75cfa@mail.gmail.com> <400d33ea0911091842i262ebf40t5a39731c6c3de7a7@mail.gmail.com> <4AF8D6D0.4010108@free.fr> Message-ID: <400d33ea0911091906md1d6cdeva01ae53e6b3b18af@mail.gmail.com> Thanks! -------------- next part -------------- A non-text attachment was scrubbed... Name: sret-demote-tests.patch Type: text/x-patch Size: 699 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091109/f2b1c70b/attachment.bin From baldrick at free.fr Mon Nov 9 21:08:54 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 10 Nov 2009 04:08:54 +0100 Subject: [llvm-commits] [llvm] r86646 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/basic.ll In-Reply-To: <200911100157.nAA1vWM3011198@zion.cs.uiuc.edu> References: <200911100157.nAA1vWM3011198@zion.cs.uiuc.edu> Message-ID: <4AF8D946.90606@free.fr> Hi Chris, > + Instruction *User = cast(U.getUser()); > + U = To; this assignment doesn't seem to be useful. Ciao, Duncan. From sabre at nondot.org Mon Nov 9 23:09:25 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 9 Nov 2009 21:09:25 -0800 Subject: [llvm-commits] [llvm] r86603 - /llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp In-Reply-To: <4AF8D4A3.60409@free.fr> References: <200911092232.nA9MWbu6002598@zion.cs.uiuc.edu> <4AF8D4A3.60409@free.fr> Message-ID: <2F6BAA6A-0C04-4189-9FB5-ACFDC4D3C776@nondot.org> On Nov 9, 2009, at 6:49 PM, Duncan Sands wrote: > Hi Chris, > >> + // This only adjusts blocks with PHI nodes. >> + if (!isa(BB->begin())) >> + return; > > don't you still want to do BB->removePredecessor in this case? it's a noop in this case too. > Anyway, if the BB doesn't start with a phi, the following code does > essentially > nothing anyway, so the test doesn't buy you much. Most blocks don't have phis, so it's a small optimization. > >> + //BB->removePredecessor(Pred, true); >> + BB->removePredecessor(Pred, true); > > One of these shouldn't be there :) Already gone. > > Also, this seems like a generally useful transform - does it really > belong > in JumpThreading? No, but I will refactor it in time, no worries :) -Chris From sabre at nondot.org Mon Nov 9 23:09:58 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 9 Nov 2009 21:09:58 -0800 Subject: [llvm-commits] [llvm] r86646 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/basic.ll In-Reply-To: <4AF8D946.90606@free.fr> References: <200911100157.nAA1vWM3011198@zion.cs.uiuc.edu> <4AF8D946.90606@free.fr> Message-ID: <290E5D6E-986E-49C3-B17A-1A06C9944EB2@nondot.org> On Nov 9, 2009, at 7:08 PM, Duncan Sands wrote: > Hi Chris, > >> + Instruction *User = cast(U.getUser()); >> + U = To; > > this assignment doesn't seem to be useful. It is equivalent to User->setOperand(U.getOperandNo(), To) but a lot faster :) -Chris From clattner at apple.com Mon Nov 9 23:16:41 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 9 Nov 2009 21:16:41 -0800 Subject: [llvm-commits] [llvm] r86651 - /llvm/trunk/lib/Target/Mips/MipsInstrFPU.td In-Reply-To: <200911100235.nAA2ZERO012563@zion.cs.uiuc.edu> References: <200911100235.nAA2ZERO012563@zion.cs.uiuc.edu> Message-ID: On Nov 9, 2009, at 6:35 PM, Bruno Cardoso Lopes wrote: > Author: bruno > Date: Mon Nov 9 20:35:13 2009 > New Revision: 86651 > > URL: http://llvm.org/viewvc/llvm-project?rev=86651&view=rev > Log: > Fix PR5445 Hey Bruno, FYI -0.0 is not the same as 0.0. -Chris > > Modified: > llvm/trunk/lib/Target/Mips/MipsInstrFPU.td > > Modified: llvm/trunk/lib/Target/Mips/MipsInstrFPU.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrFPU.td?rev=86651&r1=86650&r2=86651&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/Mips/MipsInstrFPU.td (original) > +++ llvm/trunk/lib/Target/Mips/MipsInstrFPU.td Mon Nov 9 20:35:13 > 2009 > @@ -281,7 +281,7 @@ > // Floating Point Patterns > // > = > = > = > ----------------------------------------------------------------------= > ==// > def fpimm0 : PatLeaf<(fpimm), [{ > - return N->isExactlyValue(+0.0); > + return N->isExactlyValue(+0.0) || N->isExactlyValue(-0.0); > }]>; > > def : Pat<(f32 fpimm0), (MTC1 ZERO)>; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Mon Nov 9 23:59:27 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 05:59:27 -0000 Subject: [llvm-commits] [llvm] r86666 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/Utils/Local.cpp lib/Transforms/Utils/SimplifyCFG.cpp Message-ID: <200911100559.nAA5xRel019811@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 9 23:59:26 2009 New Revision: 86666 URL: http://llvm.org/viewvc/llvm-project?rev=86666&view=rev Log: refactor TryToSimplifyUncondBranchFromEmptyBlock out of SimplifyCFG. Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h llvm/trunk/lib/Transforms/Utils/Local.cpp llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=86666&r1=86665&r2=86666&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Mon Nov 9 23:59:26 2009 @@ -85,7 +85,14 @@ /// void MergeBasicBlockIntoOnlyPred(BasicBlock *BB, Pass *P = 0); - + +/// TryToSimplifyUncondBranchFromEmptyBlock - BB is known to contain an +/// unconditional branch, and contains no instructions other than PHI nodes, +/// potential debug intrinsics and the branch. If possible, eliminate BB by +/// rewriting all the predecessors to branch to the successor block and return +/// true. If we can't transform, return false. +bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB); + /// SimplifyCFG - This function is used to do simplification of a CFG. For /// example, it adjusts branches to branches to eliminate the extra hop, it /// eliminates unreachable basic blocks, and does other "peephole" optimization Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=86666&r1=86665&r2=86666&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Mon Nov 9 23:59:26 2009 @@ -26,8 +26,11 @@ #include "llvm/Analysis/DebugInfo.h" #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Target/TargetData.h" +#include "llvm/Support/CFG.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -362,6 +365,174 @@ PredBB->eraseFromParent(); } +/// CanPropagatePredecessorsForPHIs - Return true if we can fold BB, an +/// almost-empty BB ending in an unconditional branch to Succ, into succ. +/// +/// Assumption: Succ is the single successor for BB. +/// +static bool CanPropagatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) { + assert(*succ_begin(BB) == Succ && "Succ is not successor of BB!"); + + DEBUG(errs() << "Looking to fold " << BB->getName() << " into " + << Succ->getName() << "\n"); + // Shortcut, if there is only a single predecessor it must be BB and merging + // is always safe + if (Succ->getSinglePredecessor()) return true; + + // Make a list of the predecessors of BB + typedef SmallPtrSet BlockSet; + BlockSet BBPreds(pred_begin(BB), pred_end(BB)); + + // Use that list to make another list of common predecessors of BB and Succ + BlockSet CommonPreds; + for (pred_iterator PI = pred_begin(Succ), PE = pred_end(Succ); + PI != PE; ++PI) + if (BBPreds.count(*PI)) + CommonPreds.insert(*PI); + + // Shortcut, if there are no common predecessors, merging is always safe + if (CommonPreds.empty()) + return true; + + // Look at all the phi nodes in Succ, to see if they present a conflict when + // merging these blocks + for (BasicBlock::iterator I = Succ->begin(); isa(I); ++I) { + PHINode *PN = cast(I); + + // If the incoming value from BB is again a PHINode in + // BB which has the same incoming value for *PI as PN does, we can + // merge the phi nodes and then the blocks can still be merged + PHINode *BBPN = dyn_cast(PN->getIncomingValueForBlock(BB)); + if (BBPN && BBPN->getParent() == BB) { + for (BlockSet::iterator PI = CommonPreds.begin(), PE = CommonPreds.end(); + PI != PE; PI++) { + if (BBPN->getIncomingValueForBlock(*PI) + != PN->getIncomingValueForBlock(*PI)) { + DEBUG(errs() << "Can't fold, phi node " << PN->getName() << " in " + << Succ->getName() << " is conflicting with " + << BBPN->getName() << " with regard to common predecessor " + << (*PI)->getName() << "\n"); + return false; + } + } + } else { + Value* Val = PN->getIncomingValueForBlock(BB); + for (BlockSet::iterator PI = CommonPreds.begin(), PE = CommonPreds.end(); + PI != PE; PI++) { + // See if the incoming value for the common predecessor is equal to the + // one for BB, in which case this phi node will not prevent the merging + // of the block. + if (Val != PN->getIncomingValueForBlock(*PI)) { + DEBUG(errs() << "Can't fold, phi node " << PN->getName() << " in " + << Succ->getName() << " is conflicting with regard to common " + << "predecessor " << (*PI)->getName() << "\n"); + return false; + } + } + } + } + + return true; +} + +/// TryToSimplifyUncondBranchFromEmptyBlock - BB is known to contain an +/// unconditional branch, and contains no instructions other than PHI nodes, +/// potential debug intrinsics and the branch. If possible, eliminate BB by +/// rewriting all the predecessors to branch to the successor block and return +/// true. If we can't transform, return false. +bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB) { + // We can't eliminate infinite loops. + BasicBlock *Succ = cast(BB->getTerminator())->getSuccessor(0); + if (BB == Succ) return false; + + // Check to see if merging these blocks would cause conflicts for any of the + // phi nodes in BB or Succ. If not, we can safely merge. + if (!CanPropagatePredecessorsForPHIs(BB, Succ)) return false; + + // Check for cases where Succ has multiple predecessors and a PHI node in BB + // has uses which will not disappear when the PHI nodes are merged. It is + // possible to handle such cases, but difficult: it requires checking whether + // BB dominates Succ, which is non-trivial to calculate in the case where + // Succ has multiple predecessors. Also, it requires checking whether + // constructing the necessary self-referential PHI node doesn't intoduce any + // conflicts; this isn't too difficult, but the previous code for doing this + // was incorrect. + // + // Note that if this check finds a live use, BB dominates Succ, so BB is + // something like a loop pre-header (or rarely, a part of an irreducible CFG); + // folding the branch isn't profitable in that case anyway. + if (!Succ->getSinglePredecessor()) { + BasicBlock::iterator BBI = BB->begin(); + while (isa(*BBI)) { + for (Value::use_iterator UI = BBI->use_begin(), E = BBI->use_end(); + UI != E; ++UI) { + if (PHINode* PN = dyn_cast(*UI)) { + if (PN->getIncomingBlock(UI) != BB) + return false; + } else { + return false; + } + } + ++BBI; + } + } + + DEBUG(errs() << "Killing Trivial BB: \n" << *BB); + + if (isa(Succ->begin())) { + // If there is more than one pred of succ, and there are PHI nodes in + // the successor, then we need to add incoming edges for the PHI nodes + // + const SmallVector BBPreds(pred_begin(BB), pred_end(BB)); + + // Loop over all of the PHI nodes in the successor of BB. + for (BasicBlock::iterator I = Succ->begin(); isa(I); ++I) { + PHINode *PN = cast(I); + Value *OldVal = PN->removeIncomingValue(BB, false); + assert(OldVal && "No entry in PHI for Pred BB!"); + + // If this incoming value is one of the PHI nodes in BB, the new entries + // in the PHI node are the entries from the old PHI. + if (isa(OldVal) && cast(OldVal)->getParent() == BB) { + PHINode *OldValPN = cast(OldVal); + for (unsigned i = 0, e = OldValPN->getNumIncomingValues(); i != e; ++i) + // Note that, since we are merging phi nodes and BB and Succ might + // have common predecessors, we could end up with a phi node with + // identical incoming branches. This will be cleaned up later (and + // will trigger asserts if we try to clean it up now, without also + // simplifying the corresponding conditional branch). + PN->addIncoming(OldValPN->getIncomingValue(i), + OldValPN->getIncomingBlock(i)); + } else { + // Add an incoming value for each of the new incoming values. + for (unsigned i = 0, e = BBPreds.size(); i != e; ++i) + PN->addIncoming(OldVal, BBPreds[i]); + } + } + } + + while (PHINode *PN = dyn_cast(&BB->front())) { + if (Succ->getSinglePredecessor()) { + // BB is the only predecessor of Succ, so Succ will end up with exactly + // the same predecessors BB had. + Succ->getInstList().splice(Succ->begin(), + BB->getInstList(), BB->begin()); + } else { + // We explicitly check for such uses in CanPropagatePredecessorsForPHIs. + assert(PN->use_empty() && "There shouldn't be any uses here!"); + PN->eraseFromParent(); + } + } + + // Everything that jumped to BB now goes to Succ. + BB->replaceAllUsesWith(Succ); + if (!Succ->hasName()) Succ->takeName(BB); + BB->eraseFromParent(); // Delete the old basic block. + return true; +} + + + /// OnlyUsedByDbgIntrinsics - Return true if the instruction I is only used /// by DbgIntrinsics. If DbgInUses is specified then the vector is filled /// with the DbgInfoIntrinsic that use the instruction I. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=86666&r1=86665&r2=86666&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Nov 9 23:59:26 2009 @@ -78,166 +78,6 @@ PN->addIncoming(PN->getIncomingValueForBlock(ExistPred), NewPred); } -/// CanPropagatePredecessorsForPHIs - Return true if we can fold BB, an -/// almost-empty BB ending in an unconditional branch to Succ, into succ. -/// -/// Assumption: Succ is the single successor for BB. -/// -static bool CanPropagatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) { - assert(*succ_begin(BB) == Succ && "Succ is not successor of BB!"); - - DEBUG(errs() << "Looking to fold " << BB->getName() << " into " - << Succ->getName() << "\n"); - // Shortcut, if there is only a single predecessor it must be BB and merging - // is always safe - if (Succ->getSinglePredecessor()) return true; - - // Make a list of the predecessors of BB - typedef SmallPtrSet BlockSet; - BlockSet BBPreds(pred_begin(BB), pred_end(BB)); - - // Use that list to make another list of common predecessors of BB and Succ - BlockSet CommonPreds; - for (pred_iterator PI = pred_begin(Succ), PE = pred_end(Succ); - PI != PE; ++PI) - if (BBPreds.count(*PI)) - CommonPreds.insert(*PI); - - // Shortcut, if there are no common predecessors, merging is always safe - if (CommonPreds.empty()) - return true; - - // Look at all the phi nodes in Succ, to see if they present a conflict when - // merging these blocks - for (BasicBlock::iterator I = Succ->begin(); isa(I); ++I) { - PHINode *PN = cast(I); - - // If the incoming value from BB is again a PHINode in - // BB which has the same incoming value for *PI as PN does, we can - // merge the phi nodes and then the blocks can still be merged - PHINode *BBPN = dyn_cast(PN->getIncomingValueForBlock(BB)); - if (BBPN && BBPN->getParent() == BB) { - for (BlockSet::iterator PI = CommonPreds.begin(), PE = CommonPreds.end(); - PI != PE; PI++) { - if (BBPN->getIncomingValueForBlock(*PI) - != PN->getIncomingValueForBlock(*PI)) { - DEBUG(errs() << "Can't fold, phi node " << PN->getName() << " in " - << Succ->getName() << " is conflicting with " - << BBPN->getName() << " with regard to common predecessor " - << (*PI)->getName() << "\n"); - return false; - } - } - } else { - Value* Val = PN->getIncomingValueForBlock(BB); - for (BlockSet::iterator PI = CommonPreds.begin(), PE = CommonPreds.end(); - PI != PE; PI++) { - // See if the incoming value for the common predecessor is equal to the - // one for BB, in which case this phi node will not prevent the merging - // of the block. - if (Val != PN->getIncomingValueForBlock(*PI)) { - DEBUG(errs() << "Can't fold, phi node " << PN->getName() << " in " - << Succ->getName() << " is conflicting with regard to common " - << "predecessor " << (*PI)->getName() << "\n"); - return false; - } - } - } - } - - return true; -} - -/// TryToSimplifyUncondBranchFromEmptyBlock - BB contains an unconditional -/// branch to Succ, and contains no instructions other than PHI nodes and the -/// branch. If possible, eliminate BB. -static bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB, - BasicBlock *Succ) { - // Check to see if merging these blocks would cause conflicts for any of the - // phi nodes in BB or Succ. If not, we can safely merge. - if (!CanPropagatePredecessorsForPHIs(BB, Succ)) return false; - - // Check for cases where Succ has multiple predecessors and a PHI node in BB - // has uses which will not disappear when the PHI nodes are merged. It is - // possible to handle such cases, but difficult: it requires checking whether - // BB dominates Succ, which is non-trivial to calculate in the case where - // Succ has multiple predecessors. Also, it requires checking whether - // constructing the necessary self-referential PHI node doesn't intoduce any - // conflicts; this isn't too difficult, but the previous code for doing this - // was incorrect. - // - // Note that if this check finds a live use, BB dominates Succ, so BB is - // something like a loop pre-header (or rarely, a part of an irreducible CFG); - // folding the branch isn't profitable in that case anyway. - if (!Succ->getSinglePredecessor()) { - BasicBlock::iterator BBI = BB->begin(); - while (isa(*BBI)) { - for (Value::use_iterator UI = BBI->use_begin(), E = BBI->use_end(); - UI != E; ++UI) { - if (PHINode* PN = dyn_cast(*UI)) { - if (PN->getIncomingBlock(UI) != BB) - return false; - } else { - return false; - } - } - ++BBI; - } - } - - DEBUG(errs() << "Killing Trivial BB: \n" << *BB); - - if (isa(Succ->begin())) { - // If there is more than one pred of succ, and there are PHI nodes in - // the successor, then we need to add incoming edges for the PHI nodes - // - const SmallVector BBPreds(pred_begin(BB), pred_end(BB)); - - // Loop over all of the PHI nodes in the successor of BB. - for (BasicBlock::iterator I = Succ->begin(); isa(I); ++I) { - PHINode *PN = cast(I); - Value *OldVal = PN->removeIncomingValue(BB, false); - assert(OldVal && "No entry in PHI for Pred BB!"); - - // If this incoming value is one of the PHI nodes in BB, the new entries - // in the PHI node are the entries from the old PHI. - if (isa(OldVal) && cast(OldVal)->getParent() == BB) { - PHINode *OldValPN = cast(OldVal); - for (unsigned i = 0, e = OldValPN->getNumIncomingValues(); i != e; ++i) - // Note that, since we are merging phi nodes and BB and Succ might - // have common predecessors, we could end up with a phi node with - // identical incoming branches. This will be cleaned up later (and - // will trigger asserts if we try to clean it up now, without also - // simplifying the corresponding conditional branch). - PN->addIncoming(OldValPN->getIncomingValue(i), - OldValPN->getIncomingBlock(i)); - } else { - // Add an incoming value for each of the new incoming values. - for (unsigned i = 0, e = BBPreds.size(); i != e; ++i) - PN->addIncoming(OldVal, BBPreds[i]); - } - } - } - - while (PHINode *PN = dyn_cast(&BB->front())) { - if (Succ->getSinglePredecessor()) { - // BB is the only predecessor of Succ, so Succ will end up with exactly - // the same predecessors BB had. - Succ->getInstList().splice(Succ->begin(), - BB->getInstList(), BB->begin()); - } else { - // We explicitly check for such uses in CanPropagatePredecessorsForPHIs. - assert(PN->use_empty() && "There shouldn't be any uses here!"); - PN->eraseFromParent(); - } - } - - // Everything that jumped to BB now goes to Succ. - BB->replaceAllUsesWith(Succ); - if (!Succ->hasName()) Succ->takeName(BB); - BB->eraseFromParent(); // Delete the old basic block. - return true; -} /// GetIfCondition - Given a basic block (BB) with two predecessors (and /// presumably PHI nodes in it), check to see if the merge at this block is due @@ -1983,13 +1823,11 @@ if (BI->isUnconditional()) { BasicBlock::iterator BBI = BB->getFirstNonPHI(); - BasicBlock *Succ = BI->getSuccessor(0); // Ignore dbg intrinsics. while (isa(BBI)) ++BBI; - if (BBI->isTerminator() && // Terminator is the only non-phi instruction! - Succ != BB) // Don't hurt infinite loops! - if (TryToSimplifyUncondBranchFromEmptyBlock(BB, Succ)) + if (BBI->isTerminator()) // Terminator is the only non-phi instruction! + if (TryToSimplifyUncondBranchFromEmptyBlock(BB)) return true; } else { // Conditional branch From evan.cheng at apple.com Tue Nov 10 00:38:48 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 9 Nov 2009 22:38:48 -0800 Subject: [llvm-commits] Question on emitLoadStoreInstruction() of ARMCodeEmitter.cpp In-Reply-To: <7A82351B-4D89-4F9A-A90F-D546B6F28832@apple.com> References: <7A82351B-4D89-4F9A-A90F-D546B6F28832@apple.com> Message-ID: <1098E54E-0B98-4E3F-BE64-25CE8A9883F4@apple.com> On Nov 9, 2009, at 5:46 PM, Johnny Chen wrote: > > Hi, > > I have a question wrt the following fragment of code: > > // Operand 0 of a pre- and post-indexed store is the address base > // writeback. Skip it. > bool Skipped = false; > if (IsPrePost && Form == ARMII::StFrm) { > ++OpIdx; > Skipped = true; > } > > // Set first operand > if (ImplicitRd) > // Special handling for implicit use (e.g. PC). > Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd) > << ARMII::RegRdShift); > else > Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift; > > and from the Record definition of LDRB_POST: > > def LDRB_POST { // Instruction InstARM I AI2ldbpo > field bits<32> Inst = { ?, ?, ?, ?, 0, 1, ?, 0, ?, 1, 0, > 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? }; > string Namespace = "ARM"; > dag OutOperandList = (outs GPR:$dst, GPR:$base_wb); > dag InOperandList = (ins GPR:$base, am2offset:$offset, pred:$p); > string AsmString = "ldrb${p} $dst, [$base], $offset"; > > it looks like the processing of "address base writeback" should > happen after the processing of RegRd, > if the ordering of OutOperandList followed by InOperandList is to be > observed. Is my understanding of > the ordering of the MachineOperands correct? Right. Defs comes first followed by uses. > > If this is the case, then there could be some bug in the codegen > which compensates for the incorrect > ordering/processing of base_writeback/dst? No. It's fine. The second operand is base_wb, base will be skipped. Evan > > Thanks. > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From nicholas at mxc.ca Tue Nov 10 00:46:40 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 10 Nov 2009 06:46:40 -0000 Subject: [llvm-commits] [llvm] r86667 - in /llvm/trunk: lib/Transforms/Scalar/DeadStoreElimination.cpp test/Transforms/DeadStoreElimination/lifetime.ll test/Transforms/DeadStoreElimination/memintrinsics.ll test/Transforms/DeadStoreElimination/partial-overwrite.ll Message-ID: <200911100646.nAA6kf2k021721@zion.cs.uiuc.edu> Author: nicholas Date: Tue Nov 10 00:46:40 2009 New Revision: 86667 URL: http://llvm.org/viewvc/llvm-project?rev=86667&view=rev Log: Reapply r86359, "Teach dead store elimination that certain intrinsics write to memory just like a store" with bug fixed (partial-overwrite.ll is the regression test). Added: llvm/trunk/test/Transforms/DeadStoreElimination/lifetime.ll llvm/trunk/test/Transforms/DeadStoreElimination/memintrinsics.ll llvm/trunk/test/Transforms/DeadStoreElimination/partial-overwrite.ll Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=86667&r1=86666&r2=86667&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Tue Nov 10 00:46:40 2009 @@ -78,19 +78,84 @@ FunctionPass *llvm::createDeadStoreEliminationPass() { return new DSE(); } -/// isValueAtLeastAsBigAs - Return true if V1 is greater than or equal to the -/// stored size of V2. This returns false if we don't know. +/// doesClobberMemory - Does this instruction clobber (write without reading) +/// some memory? +static bool doesClobberMemory(Instruction *I) { + if (isa(I)) + return true; + if (IntrinsicInst *II = dyn_cast(I)) { + switch (II->getIntrinsicID()) { + default: return false; + case Intrinsic::memset: case Intrinsic::memmove: case Intrinsic::memcpy: + case Intrinsic::lifetime_end: return true; + } + } + return false; +} + +/// isElidable - If the memory this instruction and the memory it writes to is +/// unused, may we delete this instrtction? +static bool isElidable(Instruction *I) { + assert(doesClobberMemory(I)); + if (IntrinsicInst *II = dyn_cast(I)) + return II->getIntrinsicID() != Intrinsic::lifetime_end; + if (StoreInst *SI = dyn_cast(I)) + return !SI->isVolatile(); + return true; +} + +/// getPointerOperand - Return the pointer that is being clobbered. +static Value *getPointerOperand(Instruction *I) { + assert(doesClobberMemory(I)); + if (StoreInst *SI = dyn_cast(I)) + return SI->getPointerOperand(); + if (MemIntrinsic *MI = dyn_cast(I)) + return MI->getOperand(1); + assert(cast(I)->getIntrinsicID() == Intrinsic::lifetime_end); + return cast(I)->getOperand(2); +} + +/// getStoreSize - Return the length in bytes of the write by the clobbering +/// instruction. If variable or unknown, returns -1. +static unsigned getStoreSize(Instruction *I, const TargetData *TD) { + assert(doesClobberMemory(I)); + if (StoreInst *SI = dyn_cast(I)) { + if (!TD) return -1u; + const PointerType *PTy = + cast(SI->getPointerOperand()->getType()); + return TD->getTypeStoreSize(PTy->getElementType()); + } + + Value *Len; + if (MemIntrinsic *MI = dyn_cast(I)) { + Len = MI->getLength(); + } else { + IntrinsicInst *II = cast(I); + assert(II->getIntrinsicID() == Intrinsic::lifetime_end); + Len = II->getOperand(0); + } + if (ConstantInt *LenCI = dyn_cast(Len)) + if (!LenCI->isAllOnesValue()) + return LenCI->getZExtValue(); + return -1u; +} + +/// isStoreAtLeastAsWideAs - Return true if the size of the store in I1 is +/// greater than or equal to the store in I2. This returns false if we don't +/// know. /// -static bool isValueAtLeastAsBigAs(Value *V1, Value *V2, const TargetData *TD) { - const Type *V1Ty = V1->getType(), *V2Ty = V2->getType(); +static bool isStoreAtLeastAsWideAs(Instruction *I1, Instruction *I2, + const TargetData *TD) { + const Type *I1Ty = getPointerOperand(I1)->getType(); + const Type *I2Ty = getPointerOperand(I2)->getType(); // Exactly the same type, must have exactly the same size. - if (V1Ty == V2Ty) return true; + if (I1Ty == I2Ty) return true; - // If we don't have target data, we don't know. - if (TD == 0) return false; + int I1Size = getStoreSize(I1, TD); + int I2Size = getStoreSize(I2, TD); - return TD->getTypeStoreSize(V1Ty) >= TD->getTypeStoreSize(V2Ty); + return I1Size != -1 && I2Size != -1 && I1Size >= I2Size; } bool DSE::runOnBasicBlock(BasicBlock &BB) { @@ -104,14 +169,9 @@ Instruction *Inst = BBI++; // If we find a store or a free, get its memory dependence. - if (!isa(Inst) && !isFreeCall(Inst)) + if (!doesClobberMemory(Inst) && !isFreeCall(Inst)) continue; - // Don't molest volatile stores or do queries that will return "clobber". - if (StoreInst *SI = dyn_cast(Inst)) - if (SI->isVolatile()) - continue; - MemDepResult InstDep = MD.getDependency(Inst); // Ignore non-local stores. @@ -124,16 +184,16 @@ continue; } - StoreInst *SI = cast(Inst); - // If not a definite must-alias dependency, ignore it. if (!InstDep.isDef()) continue; // If this is a store-store dependence, then the previous store is dead so // long as this store is at least as big as it. - if (StoreInst *DepStore = dyn_cast(InstDep.getInst())) - if (isValueAtLeastAsBigAs(SI->getOperand(0), DepStore->getOperand(0),TD)){ + if (doesClobberMemory(InstDep.getInst())) { + Instruction *DepStore = InstDep.getInst(); + if (isStoreAtLeastAsWideAs(Inst, DepStore, TD) && + isElidable(DepStore)) { // Delete the store and now-dead instructions that feed it. DeleteDeadInstruction(DepStore); NumFastStores++; @@ -146,37 +206,43 @@ --BBI; continue; } + } + + if (!isElidable(Inst)) + continue; // If we're storing the same value back to a pointer that we just // loaded from, then the store can be removed. - if (LoadInst *DepLoad = dyn_cast(InstDep.getInst())) { - if (SI->getPointerOperand() == DepLoad->getPointerOperand() && - SI->getOperand(0) == DepLoad) { - // DeleteDeadInstruction can delete the current instruction. Save BBI - // in case we need it. - WeakVH NextInst(BBI); - - DeleteDeadInstruction(SI); - - if (NextInst == 0) // Next instruction deleted. - BBI = BB.begin(); - else if (BBI != BB.begin()) // Revisit this instruction if possible. - --BBI; - NumFastStores++; - MadeChange = true; - continue; + if (StoreInst *SI = dyn_cast(Inst)) { + if (LoadInst *DepLoad = dyn_cast(InstDep.getInst())) { + if (SI->getPointerOperand() == DepLoad->getPointerOperand() && + SI->getOperand(0) == DepLoad) { + // DeleteDeadInstruction can delete the current instruction. Save BBI + // in case we need it. + WeakVH NextInst(BBI); + + DeleteDeadInstruction(SI); + + if (NextInst == 0) // Next instruction deleted. + BBI = BB.begin(); + else if (BBI != BB.begin()) // Revisit this instruction if possible. + --BBI; + NumFastStores++; + MadeChange = true; + continue; + } } } // If this is a lifetime end marker, we can throw away the store. - if (IntrinsicInst* II = dyn_cast(InstDep.getInst())) { + if (IntrinsicInst *II = dyn_cast(InstDep.getInst())) { if (II->getIntrinsicID() == Intrinsic::lifetime_end) { // Delete the store and now-dead instructions that feed it. // DeleteDeadInstruction can delete the current instruction. Save BBI // in case we need it. WeakVH NextInst(BBI); - DeleteDeadInstruction(SI); + DeleteDeadInstruction(Inst); if (NextInst == 0) // Next instruction deleted. BBI = BB.begin(); @@ -202,11 +268,11 @@ bool DSE::handleFreeWithNonTrivialDependency(Instruction *F, MemDepResult Dep) { AliasAnalysis &AA = getAnalysis(); - StoreInst *Dependency = dyn_cast_or_null(Dep.getInst()); - if (!Dependency || Dependency->isVolatile()) + Instruction *Dependency = Dep.getInst(); + if (!Dependency || !doesClobberMemory(Dependency) || !isElidable(Dependency)) return false; - Value *DepPointer = Dependency->getPointerOperand()->getUnderlyingObject(); + Value *DepPointer = getPointerOperand(Dependency)->getUnderlyingObject(); // Check for aliasing. if (AA.alias(F->getOperand(1), 1, DepPointer, 1) != @@ -251,39 +317,28 @@ --BBI; // If we find a store whose pointer is dead. - if (StoreInst* S = dyn_cast(BBI)) { - if (!S->isVolatile()) { + if (doesClobberMemory(BBI)) { + if (isElidable(BBI)) { // See through pointer-to-pointer bitcasts - Value* pointerOperand = S->getPointerOperand()->getUnderlyingObject(); + Value *pointerOperand = getPointerOperand(BBI)->getUnderlyingObject(); // Alloca'd pointers or byval arguments (which are functionally like // alloca's) are valid candidates for removal. if (deadPointers.count(pointerOperand)) { // DCE instructions only used to calculate that store. + Instruction *Dead = BBI; BBI++; - DeleteDeadInstruction(S, &deadPointers); + DeleteDeadInstruction(Dead, &deadPointers); NumFastStores++; MadeChange = true; + continue; } } - continue; - } - - // We can also remove memcpy's to local variables at the end of a function. - if (MemCpyInst *M = dyn_cast(BBI)) { - Value *dest = M->getDest()->getUnderlyingObject(); - - if (deadPointers.count(dest)) { - BBI++; - DeleteDeadInstruction(M, &deadPointers); - NumFastOther++; - MadeChange = true; + // Because a memcpy or memmove is also a load, we can't skip it if we + // didn't remove it. + if (!isa(BBI)) continue; - } - - // Because a memcpy is also a load, we can't skip it if we didn't remove - // it. } Value* killPointer = 0; @@ -304,11 +359,11 @@ killPointer = L->getPointerOperand(); } else if (VAArgInst* V = dyn_cast(BBI)) { killPointer = V->getOperand(0); - } else if (isa(BBI) && - isa(cast(BBI)->getLength())) { - killPointer = cast(BBI)->getSource(); + } else if (isa(BBI) && + isa(cast(BBI)->getLength())) { + killPointer = cast(BBI)->getSource(); killPointerSize = cast( - cast(BBI)->getLength())->getZExtValue(); + cast(BBI)->getLength())->getZExtValue(); } else if (AllocaInst* A = dyn_cast(BBI)) { deadPointers.erase(A); Added: llvm/trunk/test/Transforms/DeadStoreElimination/lifetime.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/lifetime.ll?rev=86667&view=auto ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/lifetime.ll (added) +++ llvm/trunk/test/Transforms/DeadStoreElimination/lifetime.ll Tue Nov 10 00:46:40 2009 @@ -0,0 +1,19 @@ +; RUN: opt -S -dse < %s | FileCheck %s + +declare void @llvm.lifetime.end(i64, i8*) +declare void @llvm.memset.i8(i8*, i8, i8, i32) + +define void @test1() { +; CHECK: @test1 + %A = alloca i8 + + store i8 0, i8* %A ;; Written to by memset + call void @llvm.lifetime.end(i64 1, i8* %A) +; CHECK: lifetime.end + + call void @llvm.memset.i8(i8* %A, i8 0, i8 -1, i32 0) +; CHECK-NOT: memset + + ret void +; CHECK: ret void +} Added: llvm/trunk/test/Transforms/DeadStoreElimination/memintrinsics.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/memintrinsics.ll?rev=86667&view=auto ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/memintrinsics.ll (added) +++ llvm/trunk/test/Transforms/DeadStoreElimination/memintrinsics.ll Tue Nov 10 00:46:40 2009 @@ -0,0 +1,47 @@ +; RUN: opt -S -dse < %s | FileCheck %s + +declare void @llvm.memcpy.i8(i8*, i8*, i8, i32) +declare void @llvm.memmove.i8(i8*, i8*, i8, i32) +declare void @llvm.memset.i8(i8*, i8, i8, i32) + +define void @test1() { +; CHECK: @test1 + %A = alloca i8 + %B = alloca i8 + + store i8 0, i8* %A ;; Written to by memcpy +; CHECK-NOT: store + + call void @llvm.memcpy.i8(i8* %A, i8* %B, i8 -1, i32 0) + + ret void +; CHECK: ret void +} + +define void @test2() { +; CHECK: @test2 + %A = alloca i8 + %B = alloca i8 + + store i8 0, i8* %A ;; Written to by memmove +; CHECK-NOT: store + + call void @llvm.memmove.i8(i8* %A, i8* %B, i8 -1, i32 0) + + ret void +; CHECK: ret void +} + +define void @test3() { +; CHECK: @test3 + %A = alloca i8 + %B = alloca i8 + + store i8 0, i8* %A ;; Written to by memset +; CHECK-NOT: store + + call void @llvm.memset.i8(i8* %A, i8 0, i8 -1, i32 0) + + ret void +; CHECK: ret void +} Added: llvm/trunk/test/Transforms/DeadStoreElimination/partial-overwrite.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/partial-overwrite.ll?rev=86667&view=auto ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/partial-overwrite.ll (added) +++ llvm/trunk/test/Transforms/DeadStoreElimination/partial-overwrite.ll Tue Nov 10 00:46:40 2009 @@ -0,0 +1,14 @@ +; RUN: opt -dse -S %s | FileCheck %s +; Note that we could do better by merging the two stores into one. + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + +define void @test(i32* %P) { + store i32 0, i32* %P +; CHECK: store i32 + %Q = bitcast i32* %P to i16* + store i16 1, i16* %Q +; CHECK: store i16 + ret void +} From nicholas at mxc.ca Tue Nov 10 01:00:44 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 10 Nov 2009 07:00:44 -0000 Subject: [llvm-commits] [llvm] r86668 - /llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Message-ID: <200911100700.nAA70iQi022203@zion.cs.uiuc.edu> Author: nicholas Date: Tue Nov 10 01:00:43 2009 New Revision: 86668 URL: http://llvm.org/viewvc/llvm-project?rev=86668&view=rev Log: Simplify. Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=86668&r1=86667&r2=86668&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Tue Nov 10 01:00:43 2009 @@ -121,9 +121,7 @@ assert(doesClobberMemory(I)); if (StoreInst *SI = dyn_cast(I)) { if (!TD) return -1u; - const PointerType *PTy = - cast(SI->getPointerOperand()->getType()); - return TD->getTypeStoreSize(PTy->getElementType()); + return TD->getTypeStoreSize(SI->getOperand(0)->getType()); } Value *Len; From sabre at nondot.org Tue Nov 10 01:23:37 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 07:23:37 -0000 Subject: [llvm-commits] [llvm] r86670 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/cast-mul-select.ll test/Transforms/InstCombine/cast.ll Message-ID: <200911100723.nAA7Nc5X022955@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 01:23:37 2009 New Revision: 86670 URL: http://llvm.org/viewvc/llvm-project?rev=86670&view=rev Log: unify the code that determines whether it is a good idea to change the type of a computation. This fixes some infinite loops when dealing with TD that has no native types. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/cast-mul-select.ll llvm/trunk/test/Transforms/InstCombine/cast.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=86670&r1=86669&r2=86670&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Nov 10 01:23:37 2009 @@ -477,6 +477,34 @@ return Ty; } +/// ShouldChangeType - Return true if it is desirable to convert a computation +/// from 'From' to 'To'. We don't want to convert from a legal to an illegal +/// type for example, or from a smaller to a larger illegal type. +static bool ShouldChangeType(const Type *From, const Type *To, + const TargetData *TD) { + assert(isa(From) && isa(To)); + + // If we don't have TD, we don't know if the source/dest are legal. + if (!TD) return false; + + unsigned FromWidth = From->getPrimitiveSizeInBits(); + unsigned ToWidth = To->getPrimitiveSizeInBits(); + bool FromLegal = TD->isLegalInteger(FromWidth); + bool ToLegal = TD->isLegalInteger(ToWidth); + + // If this is a legal integer from type, and the result would be an illegal + // type, don't do the transformation. + if (FromLegal && !ToLegal) + return false; + + // Otherwise, if both are illegal, do not increase the size of the result. We + // do allow things like i160 -> i64, but not i64 -> i160. + if (!FromLegal && !ToLegal && ToWidth > FromWidth) + return false; + + return true; +} + /// getBitCastOperand - If the specified operand is a CastInst, a constant /// expression bitcast, or a GetElementPtrInst with all zero indices, return the /// operand value, otherwise return null. @@ -8082,11 +8110,9 @@ // it is currently legal. if (!isa(Src->getType()) || !isa(CI.getType()) || - (TD && TD->isLegalInteger(CI.getType()->getPrimitiveSizeInBits())) || - (TD && !TD->isLegalInteger(Src->getType()->getPrimitiveSizeInBits()))) + ShouldChangeType(CI.getType(), Src->getType(), TD)) if (Instruction *NV = FoldOpIntoPhi(CI)) return NV; - } return 0; @@ -8235,10 +8261,8 @@ // Only do this if the dest type is a simple type, don't convert the // expression tree to something weird like i93 unless the source is also // strange. - if (TD && - (TD->isLegalInteger(DestTy->getScalarType()->getPrimitiveSizeInBits()) || - !TD->isLegalInteger((SrcI->getType()->getScalarType() - ->getPrimitiveSizeInBits()))) && + if (!isa(SrcI->getType()) || + ShouldChangeType(SrcI->getType(), DestTy, TD) && CanEvaluateInDifferentType(SrcI, DestTy, CI.getOpcode(), NumCastsRemoved)) { // If this cast is a truncate, evaluting in a different type always @@ -10784,9 +10808,10 @@ } -// FoldPHIArgOpIntoPHI - If all operands to a PHI node are the same "unary" -// operator and they all are only used by the PHI, PHI together their -// inputs, and do the operation once, to the result of the PHI. + +/// FoldPHIArgOpIntoPHI - If all operands to a PHI node are the same "unary" +/// operator and they all are only used by the PHI, PHI together their +/// inputs, and do the operation once, to the result of the PHI. Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) { Instruction *FirstInst = cast(PN.getIncomingValue(0)); @@ -10808,23 +10833,7 @@ // Be careful about transforming integer PHIs. We don't want to pessimize // the code by turning an i32 into an i1293. if (isa(PN.getType()) && isa(CastSrcTy)) { - // If we don't have TD, we don't know if the original PHI was legal. - if (!TD) return 0; - - unsigned PHIWidth = PN.getType()->getPrimitiveSizeInBits(); - unsigned NewWidth = CastSrcTy->getPrimitiveSizeInBits(); - bool PHILegal = TD->isLegalInteger(PHIWidth); - bool NewLegal = TD->isLegalInteger(NewWidth); - - // If this is a legal integer PHI node, and pulling the operation through - // would cause it to be an illegal integer PHI, don't do the - // transformation. - if (PHILegal && !NewLegal) - return 0; - - // Otherwise, if both are illegal, do not increase the size of the PHI. We - // do allow things like i160 -> i64, but not i64 -> i160. - if (!PHILegal && !NewLegal && NewWidth > PHIWidth) + if (!ShouldChangeType(PN.getType(), CastSrcTy, TD)) return 0; } } else if (isa(FirstInst) || isa(FirstInst)) { Modified: llvm/trunk/test/Transforms/InstCombine/cast-mul-select.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/cast-mul-select.ll?rev=86670&r1=86669&r2=86670&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/cast-mul-select.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/cast-mul-select.ll Tue Nov 10 01:23:37 2009 @@ -1,6 +1,6 @@ ; RUN: opt < %s -instcombine -S | FileCheck %s -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32" define i32 @mul(i32 %x, i32 %y) { %A = trunc i32 %x to i8 Modified: llvm/trunk/test/Transforms/InstCombine/cast.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/cast.ll?rev=86670&r1=86669&r2=86670&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/cast.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/cast.ll Tue Nov 10 01:23:37 2009 @@ -1,6 +1,6 @@ ; Tests to make sure elimination of casts is working correctly ; RUN: opt < %s -instcombine -S | FileCheck %s -target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64" @inbuf = external global [32832 x i8] ; <[32832 x i8]*> [#uses=1] From sabre at nondot.org Tue Nov 10 01:44:36 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 07:44:36 -0000 Subject: [llvm-commits] [llvm] r86672 - /llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll Message-ID: <200911100744.nAA7ibJ1023609@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 01:44:36 2009 New Revision: 86672 URL: http://llvm.org/viewvc/llvm-project?rev=86672&view=rev Log: optimize test Modified: llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll Modified: llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll?rev=86672&r1=86671&r2=86672&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll (original) +++ llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll Tue Nov 10 01:44:36 2009 @@ -1,4 +1,4 @@ -; RUN: opt < %s -simplifycfg | llvm-dis +; RUN: opt < %s -simplifycfg -S ; PR3016 ; Dead use caused invariant violation. From vhernandez at apple.com Tue Nov 10 02:28:36 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Tue, 10 Nov 2009 08:28:36 -0000 Subject: [llvm-commits] [llvm] r86675 - in /llvm/trunk: include/llvm/Analysis/ValueTracking.h lib/Analysis/ValueTracking.cpp Message-ID: <200911100828.nAA8Safm025512@zion.cs.uiuc.edu> Author: hernande Date: Tue Nov 10 02:28:35 2009 New Revision: 86675 URL: http://llvm.org/viewvc/llvm-project?rev=86675&view=rev Log: Add ComputeMultiple() analysis function that recursively determines if a Value V is a multiple of unsigned Base Modified: llvm/trunk/include/llvm/Analysis/ValueTracking.h llvm/trunk/lib/Analysis/ValueTracking.cpp Modified: llvm/trunk/include/llvm/Analysis/ValueTracking.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ValueTracking.h?rev=86675&r1=86674&r2=86675&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ValueTracking.h (original) +++ llvm/trunk/include/llvm/Analysis/ValueTracking.h Tue Nov 10 02:28:35 2009 @@ -63,6 +63,15 @@ unsigned ComputeNumSignBits(Value *Op, const TargetData *TD = 0, unsigned Depth = 0); + /// ComputeMultiple - This function computes the integer multiple of Base that + /// equals V. If successful, it returns true and returns the multiple in + /// Multiple. If unsuccessful, it returns false. Also, if V can be + /// simplified to an integer, then the simplified V is returned in Val. Look + /// through sext only if LookThroughSExt=true. + bool ComputeMultiple(Value *V, unsigned Base, Value *&Multiple, APInt &Val, + bool LookThroughSExt = false, const TargetData *TD = 0, + unsigned Depth = 0); + /// CannotBeNegativeZero - Return true if we can prove that the specified FP /// value is never equal to -0.0. /// Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=86675&r1=86674&r2=86675&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ValueTracking.cpp (original) +++ llvm/trunk/lib/Analysis/ValueTracking.cpp Tue Nov 10 02:28:35 2009 @@ -789,6 +789,131 @@ return std::max(FirstAnswer, std::min(TyBits, Mask.countLeadingZeros())); } +/// ComputeMultiple - This function computes the integer multiple of Base that +/// equals V. If successful, it returns true and returns the multiple in +/// Multiple. If unsuccessful, it returns false. Also, if V can be +/// simplified to an integer, then the simplified V is returned in Val. It looks +/// through SExt instructions only if LookThroughSExt is true. +bool llvm::ComputeMultiple(Value *V, unsigned Base, Value *&Multiple, + APInt &Val, bool LookThroughSExt, + const TargetData *TD, unsigned Depth) { + const unsigned MaxDepth = 6; + + assert(TD && V && "No Value?"); + assert(Depth <= MaxDepth && "Limit Search Depth"); + assert(V->getType()->isInteger() && "Not integer or pointer type!"); + + const Type *T = V->getType(); + unsigned TSize = TD->getTypeSizeInBits(T->getScalarType()); + + ConstantInt *CI = NULL; + if ((CI = dyn_cast(V))) + Val = CI->getValue(); + + if (Base == 0) + return false; + + if (Base == 1) { + Multiple = V; + return true; + } + + ConstantExpr *CO = dyn_cast(V); + Constant *BaseVal = ConstantInt::get(T, Base); + if (CO && CO == BaseVal) { + // Multiple is 1. + Multiple = ConstantInt::get(T, 1); + return true; + } + + if (CI && CI->getZExtValue() % Base == 0) { + Multiple = ConstantInt::get(T, CI->getZExtValue() / Base); + return true; + } + + if (Depth == MaxDepth) return false; // Limit search depth. + + Operator *I = dyn_cast(V); + if (!I) return false; + + switch (I->getOpcode()) { + default: break; + case Instruction::SExt: { + if (!LookThroughSExt) return false; + // otherwise fall through to ZExt + } + case Instruction::ZExt: { + return ComputeMultiple(I->getOperand(0), Base, Multiple, Val, + LookThroughSExt, TD, Depth+1); + } + case Instruction::Shl: + case Instruction::Mul: { + Value *Op0 = I->getOperand(0); + Value *Op1 = I->getOperand(1); + + if (I->getOpcode() == Instruction::Shl) { + ConstantInt *Op1CI = dyn_cast(Op1); + if (!Op1CI) return false; + // Turn Op0 << Op1 into Op0 * 2^Op1 + APInt Op1Int = Op1CI->getValue(); + uint64_t BitToSet = Op1Int.getLimitedValue(Op1Int.getBitWidth() - 1); + Op1 = ConstantInt::get(V->getContext(), + APInt(Op1Int.getBitWidth(), 0).set(BitToSet)); + } + + Value *Mul0 = NULL; + Value *Mul1 = NULL; + APInt Val0(TSize, 0), Val1(TSize, 0); + bool M0 = ComputeMultiple(Op0, Base, Mul0, Val0, + LookThroughSExt, TD, Depth+1); + bool M1 = ComputeMultiple(Op1, Base, Mul1, Val1, + LookThroughSExt, TD, Depth+1); + + if (M0) { + if (isa(Op1) && isa(Mul0)) { + // V == Base * (Mul0 * Op1), so return (Mul0 * Op1) + Multiple = ConstantExpr::getMul(cast(Mul0), + Val1.getBoolValue() ? ConstantInt::get(V->getContext(), Val1): + cast(Op1)); + return true; + } + + if (ConstantInt *Mul0CI = dyn_cast(Mul0)) + if (Mul0CI->getValue() == 1) { + // V == Base * Op1, so return Op1 + Multiple = Op1; + return true; + } + } + + if (M1) { + if (isa(Op0) && isa(Mul1)) { + // V == Base * (Mul1 * Op0), so return (Mul1 * Op0) + Multiple = ConstantExpr::getMul(cast(Mul1), + Val0.getBoolValue() ? ConstantInt::get(V->getContext(), Val0): + cast(Op0)); + return true; + } + + if (ConstantInt *Mul1CI = dyn_cast(Mul1)) + if (Mul1CI->getValue() == 1) { + // V == Base * Op0, so return Op0 + Multiple = Op0; + return true; + } + } + + if (Val0.getBoolValue() && Val1.getBoolValue()) + // Op1*Op2 was simplified, try computing multiple again. + return ComputeMultiple(ConstantInt::get(V->getContext(), Val0 * Val1), + Base, Multiple, Val, LookThroughSExt, TD, Depth+1); + } + } + + // We could not determine if V is a multiple of Base. + return false; +} + /// CannotBeNegativeZero - Return true if we can prove that the specified FP /// value is never equal to -0.0. /// From vhernandez at apple.com Tue Nov 10 02:32:26 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Tue, 10 Nov 2009 08:32:26 -0000 Subject: [llvm-commits] [llvm] r86676 - in /llvm/trunk: include/llvm/Analysis/MemoryBuiltins.h lib/Analysis/MemoryBuiltins.cpp lib/Transforms/IPO/GlobalOpt.cpp test/Analysis/PointerTracking/sizes.ll Message-ID: <200911100832.nAA8WRXI025771@zion.cs.uiuc.edu> Author: hernande Date: Tue Nov 10 02:32:25 2009 New Revision: 86676 URL: http://llvm.org/viewvc/llvm-project?rev=86676&view=rev Log: Update computeArraySize() to use ComputeMultiple() to determine the array size associated with a malloc; also extend PerformHeapAllocSRoA() to check if the optimized malloc's arg had its highest bit set, so that it is safe for ComputeMultiple() to look through sext instructions while determining the optimized malloc's array size Modified: llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h llvm/trunk/lib/Analysis/MemoryBuiltins.cpp llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp llvm/trunk/test/Analysis/PointerTracking/sizes.ll Modified: llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h?rev=86676&r1=86675&r2=86676&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h Tue Nov 10 02:32:25 2009 @@ -44,9 +44,7 @@ /// isArrayMalloc - Returns the corresponding CallInst if the instruction /// is a call to malloc whose array size can be determined and the array size /// is not constant 1. Otherwise, return NULL. -CallInst *isArrayMalloc(Value *I, const TargetData *TD); -const CallInst *isArrayMalloc(const Value *I, - const TargetData *TD); +const CallInst *isArrayMalloc(const Value *I, const TargetData *TD); /// getMallocType - Returns the PointerType resulting from the malloc call. /// The PointerType depends on the number of bitcast uses of the malloc call: @@ -67,7 +65,8 @@ /// then return that multiple. For non-array mallocs, the multiple is /// constant 1. Otherwise, return NULL for mallocs whose array size cannot be /// determined. -Value *getMallocArraySize(CallInst *CI, const TargetData *TD); +Value *getMallocArraySize(CallInst *CI, const TargetData *TD, + bool LookThroughSExt = false); //===----------------------------------------------------------------------===// // free Call Utility Functions. Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?rev=86676&r1=86675&r2=86676&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Tue Nov 10 02:32:25 2009 @@ -16,7 +16,7 @@ #include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/Module.h" -#include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/Target/TargetData.h" using namespace llvm; @@ -87,12 +87,8 @@ : NULL; } -/// isConstantOne - Return true only if val is constant int 1. -static bool isConstantOne(Value *val) { - return isa(val) && cast(val)->isOne(); -} - -static Value *isArrayMallocHelper(const CallInst *CI, const TargetData *TD) { +static Value *computeArraySize(const CallInst *CI, const TargetData *TD, + bool LookThroughSExt = false) { if (!CI) return NULL; @@ -101,97 +97,28 @@ if (!T || !T->isSized() || !TD) return NULL; - Value *MallocArg = CI->getOperand(1); - const Type *ArgType = MallocArg->getType(); - ConstantExpr *CO = dyn_cast(MallocArg); - BinaryOperator *BO = dyn_cast(MallocArg); - - unsigned ElementSizeInt = TD->getTypeAllocSize(T); + unsigned ElementSize = TD->getTypeAllocSize(T); if (const StructType *ST = dyn_cast(T)) - ElementSizeInt = TD->getStructLayout(ST)->getSizeInBytes(); - Constant *ElementSize = ConstantInt::get(ArgType, ElementSizeInt); - - // First, check if CI is a non-array malloc. - if (CO && CO == ElementSize) - // Match CreateMalloc's use of constant 1 array-size for non-array mallocs. - return ConstantInt::get(ArgType, 1); - - // Second, check if CI is an array malloc whose array size can be determined. - if (isConstantOne(ElementSize)) - return MallocArg; - - if (ConstantInt *CInt = dyn_cast(MallocArg)) - if (CInt->getZExtValue() % ElementSizeInt == 0) - return ConstantInt::get(ArgType, CInt->getZExtValue() / ElementSizeInt); - - if (!CO && !BO) - return NULL; - - Value *Op0 = NULL; - Value *Op1 = NULL; - unsigned Opcode = 0; - if (CO && ((CO->getOpcode() == Instruction::Mul) || - (CO->getOpcode() == Instruction::Shl))) { - Op0 = CO->getOperand(0); - Op1 = CO->getOperand(1); - Opcode = CO->getOpcode(); - } - if (BO && ((BO->getOpcode() == Instruction::Mul) || - (BO->getOpcode() == Instruction::Shl))) { - Op0 = BO->getOperand(0); - Op1 = BO->getOperand(1); - Opcode = BO->getOpcode(); - } + ElementSize = TD->getStructLayout(ST)->getSizeInBytes(); - // Determine array size if malloc's argument is the product of a mul or shl. - if (Op0) { - if (Opcode == Instruction::Mul) { - if (Op1 == ElementSize) - // ArraySize * ElementSize - return Op0; - if (Op0 == ElementSize) - // ElementSize * ArraySize - return Op1; - } - if (Opcode == Instruction::Shl) { - ConstantInt *Op1CI = dyn_cast(Op1); - if (!Op1CI) return NULL; - - APInt Op1Int = Op1CI->getValue(); - uint64_t BitToSet = Op1Int.getLimitedValue(Op1Int.getBitWidth() - 1); - Value *Op1Pow = ConstantInt::get(Op1CI->getContext(), - APInt(Op1Int.getBitWidth(), 0).set(BitToSet)); - if (Op0 == ElementSize) - // ArraySize << log2(ElementSize) - return Op1Pow; - if (Op1Pow == ElementSize) - // ElementSize << log2(ArraySize) - return Op0; - } - } + // If malloc calls' arg can be determined to be a multiple of ElementSize, + // return the multiple. Otherwise, return NULL. + Value *MallocArg = CI->getOperand(1); + Value *Multiple = NULL; + APInt Val(TD->getTypeSizeInBits(MallocArg->getType()->getScalarType()), 0); + if (ComputeMultiple(MallocArg, ElementSize, Multiple, + Val, LookThroughSExt, TD)) + return Multiple; - // We could not determine the malloc array size from MallocArg. return NULL; } /// isArrayMalloc - Returns the corresponding CallInst if the instruction /// is a call to malloc whose array size can be determined and the array size /// is not constant 1. Otherwise, return NULL. -CallInst *llvm::isArrayMalloc(Value *I, const TargetData *TD) { - CallInst *CI = extractMallocCall(I); - Value *ArraySize = isArrayMallocHelper(CI, TD); - - if (ArraySize && - ArraySize != ConstantInt::get(CI->getOperand(1)->getType(), 1)) - return CI; - - // CI is a non-array malloc or we can't figure out that it is an array malloc. - return NULL; -} - const CallInst *llvm::isArrayMalloc(const Value *I, const TargetData *TD) { const CallInst *CI = extractMallocCall(I); - Value *ArraySize = isArrayMallocHelper(CI, TD); + Value *ArraySize = computeArraySize(CI, TD); if (ArraySize && ArraySize != ConstantInt::get(CI->getOperand(1)->getType(), 1)) @@ -207,7 +134,7 @@ /// 1: PointerType is the bitcast's result type. /// >1: Unique PointerType cannot be determined, return NULL. const PointerType *llvm::getMallocType(const CallInst *CI) { - assert(isMalloc(CI) && "GetMallocType and not malloc call"); + assert(isMalloc(CI) && "getMallocType and not malloc call"); const PointerType *MallocType = NULL; unsigned NumOfBitCastUses = 0; @@ -247,8 +174,10 @@ /// then return that multiple. For non-array mallocs, the multiple is /// constant 1. Otherwise, return NULL for mallocs whose array size cannot be /// determined. -Value *llvm::getMallocArraySize(CallInst *CI, const TargetData *TD) { - return isArrayMallocHelper(CI, TD); +Value *llvm::getMallocArraySize(CallInst *CI, const TargetData *TD, + bool LookThroughSExt) { + assert(isMalloc(CI) && "getMallocArraySize and not malloc call"); + return computeArraySize(CI, TD, LookThroughSExt); } //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=86676&r1=86675&r2=86676&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Tue Nov 10 02:32:25 2009 @@ -1321,15 +1321,15 @@ // if (F1) { free(F1); F1 = 0; } // if (F2) { free(F2); F2 = 0; } // } - Value *RunningOr = 0; + // The malloc can also fail if its argument is too large. + Constant *ConstantZero = ConstantInt::get(CI->getOperand(1)->getType(), 0); + Value *RunningOr = new ICmpInst(CI, ICmpInst::ICMP_SLT, CI->getOperand(1), + ConstantZero, "isneg"); for (unsigned i = 0, e = FieldMallocs.size(); i != e; ++i) { Value *Cond = new ICmpInst(CI, ICmpInst::ICMP_EQ, FieldMallocs[i], Constant::getNullValue(FieldMallocs[i]->getType()), "isnull"); - if (!RunningOr) - RunningOr = Cond; // First seteq - else - RunningOr = BinaryOperator::CreateOr(RunningOr, Cond, "tmp", CI); + RunningOr = BinaryOperator::CreateOr(RunningOr, Cond, "tmp", CI); } // Split the basic block at the old malloc. @@ -1490,7 +1490,7 @@ // This eliminates dynamic allocation, avoids an indirection accessing the // data, and exposes the resultant global to further GlobalOpt. // We cannot optimize the malloc if we cannot determine malloc array size. - if (Value *NElems = getMallocArraySize(CI, TD)) { + if (Value *NElems = getMallocArraySize(CI, TD, true)) { if (ConstantInt *NElements = dyn_cast(NElems)) // Restrict this transformation to only working on small allocations // (2048 bytes currently), as we don't want to introduce a 16M global or @@ -1535,7 +1535,7 @@ extractMallocCallFromBitCast(Malloc) : cast(Malloc); } - GVI = PerformHeapAllocSRoA(GV, CI, getMallocArraySize(CI, TD), TD); + GVI = PerformHeapAllocSRoA(GV, CI, getMallocArraySize(CI, TD, true),TD); return true; } } Modified: llvm/trunk/test/Analysis/PointerTracking/sizes.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/PointerTracking/sizes.ll?rev=86676&r1=86675&r2=86676&view=diff ============================================================================== --- llvm/trunk/test/Analysis/PointerTracking/sizes.ll (original) +++ llvm/trunk/test/Analysis/PointerTracking/sizes.ll Tue Nov 10 02:32:25 2009 @@ -31,7 +31,6 @@ } declare i32 @bar(i8*) -declare i32 @bar2(i64*) define i32 @foo1(i32 %n) nounwind { entry: @@ -66,11 +65,6 @@ %call = tail call i8* @malloc(i64 %n) ; [#uses=1] ; CHECK: %call = ; CHECK: ==> %n elements, %n bytes allocated - %mallocsize = mul i64 %n, 8 ; [#uses=1] - %malloccall = tail call i8* @malloc(i64 %mallocsize) ; [#uses=1] - %call3 = bitcast i8* %malloccall to i64* ; [#uses=1] -; CHECK: %malloccall = -; CHECK: ==> (8 * %n) elements, (8 * %n) bytes allocated %call2 = tail call i8* @calloc(i64 2, i64 4) nounwind ; [#uses=1] ; CHECK: %call2 = ; CHECK: ==> 8 elements, 8 bytes allocated @@ -78,12 +72,10 @@ ; CHECK: %call4 = ; CHECK: ==> 16 elements, 16 bytes allocated %call6 = tail call i32 @bar(i8* %call) nounwind ; [#uses=1] - %call7 = tail call i32 @bar2(i64* %call3) nounwind ; [#uses=1] %call8 = tail call i32 @bar(i8* %call2) nounwind ; [#uses=1] %call10 = tail call i32 @bar(i8* %call4) nounwind ; [#uses=1] %add = add i32 %call8, %call6 ; [#uses=1] - %add10 = add i32 %add, %call7 ; [#uses=1] - %add11 = add i32 %add10, %call10 ; [#uses=1] + %add11 = add i32 %add, %call10 ; [#uses=1] ret i32 %add11 } From baldrick at free.fr Tue Nov 10 02:42:50 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 10 Nov 2009 09:42:50 +0100 Subject: [llvm-commits] [llvm] r86670 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/cast-mul-select.ll test/Transforms/InstCombine/cast.ll In-Reply-To: <200911100723.nAA7Nc5X022955@zion.cs.uiuc.edu> References: <200911100723.nAA7Nc5X022955@zion.cs.uiuc.edu> Message-ID: <4AF9278A.6010803@free.fr> Hi Chris, > + // If we don't have TD, we don't know if the source/dest are legal. > + if (!TD) return false; I guess it is reasonable to assume that if the number of bits is not divisible by 8 then it is illegal. That said, would adding this case buy much? Ciao, Duncan. From baldrick at free.fr Tue Nov 10 03:08:11 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 10 Nov 2009 09:08:11 -0000 Subject: [llvm-commits] [llvm] r86678 - in /llvm/trunk/lib/CodeGen: IntrinsicLowering.cpp SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200911100908.nAA98CZm007894@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 10 03:08:09 2009 New Revision: 86678 URL: http://llvm.org/viewvc/llvm-project?rev=86678&view=rev Log: Codegen support for the llvm.invariant/lifetime.start/end intrinsics: just throw them away. Modified: llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp?rev=86678&r1=86677&r2=86678&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp Tue Nov 10 03:08:09 2009 @@ -515,6 +515,15 @@ if (CI->getType() != Type::getVoidTy(Context)) CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); break; + case Intrinsic::invariant_start: + case Intrinsic::lifetime_start: + // Discard region information. + CI->replaceAllUsesWith(UndefValue::get(CI->getType())); + break; + case Intrinsic::invariant_end: + case Intrinsic::lifetime_end: + // Discard region information. + break; } assert(CI->use_empty() && Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=86678&r1=86677&r2=86678&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Tue Nov 10 03:08:09 2009 @@ -4409,6 +4409,16 @@ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMAX); case Intrinsic::atomic_swap: return implVisitBinaryAtomic(I, ISD::ATOMIC_SWAP); + + case Intrinsic::invariant_start: + case Intrinsic::lifetime_start: + // Discard region information. + setValue(&I, DAG.getUNDEF(TLI.getPointerTy())); + return 0; + case Intrinsic::invariant_end: + case Intrinsic::lifetime_end: + // Discard region information. + return 0; } } From evan.cheng at apple.com Tue Nov 10 03:27:15 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 10 Nov 2009 01:27:15 -0800 Subject: [llvm-commits] [llvm] r86404 - in /llvm/trunk/lib/Target/ARM: ARMAddressingModes.h ARMISelDAGToDAG.cpp ARMInstrInfo.td AsmPrinter/ARMAsmPrinter.cpp NEONPreAllocPass.cpp In-Reply-To: <200911072125.nA7LPdh9002578@zion.cs.uiuc.edu> References: <200911072125.nA7LPdh9002578@zion.cs.uiuc.edu> Message-ID: <90BAE2B3-491D-4D6F-BA26-4A9CD2E54B84@apple.com> On Nov 7, 2009, at 1:25 PM, Jim Grosbach wrote: > > > bool ARMDAGToDAGISel::SelectAddrMode6(SDValue Op, SDValue N, > SDValue &Addr, SDValue &Update, > - SDValue &Opc) { > + SDValue &Opc, SDValue &Align) { > Addr = N; > // Default to no writeback. > Update = CurDAG->getRegister(0, MVT::i32); > Opc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(false), MVT::i32); > + // Default to no alignment. > + Align = CurDAG->getTargetConstant(0, MVT::i32); > return true; > } Shouldn't we be able to transfer the alignment on the LoadSDNode / StoreSDNode to Align (capped at 64 / 128 for 64-bit / 128-bit memory operations)? Evan > > @@ -1008,8 +1010,8 @@ > SDNode *N = Op.getNode(); > DebugLoc dl = N->getDebugLoc(); > > - SDValue MemAddr, MemUpdate, MemOpc; > - if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, > MemOpc)) > + SDValue MemAddr, MemUpdate, MemOpc, Align; > + if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, > MemOpc, Align)) > return NULL; > > SDValue Chain = N->getOperand(0); > @@ -1034,10 +1036,10 @@ > > if (is64BitVector) { > unsigned Opc = DOpcodes[OpcodeIndex]; > - const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Chain }; > + const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Align, > Chain }; > std::vector ResTys(NumVecs, VT); > ResTys.push_back(MVT::Other); > - return CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 4); > + return CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5); > } > > EVT RegVT = GetNEONSubregVT(VT); > @@ -1045,10 +1047,10 @@ > // Quad registers are directly supported for VLD2, > // loading 2 pairs of D regs. > unsigned Opc = QOpcodes0[OpcodeIndex]; > - const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Chain }; > + const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Align, > Chain }; > std::vector ResTys(4, VT); > ResTys.push_back(MVT::Other); > - SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 4); > + SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5); > Chain = SDValue(VLd, 4); > > // Combine the even and odd subregs to produce the result. > @@ -1069,14 +1071,15 @@ > > // Load the even subregs. > unsigned Opc = QOpcodes0[OpcodeIndex]; > - const SDValue OpsA[] = { MemAddr, MemUpdate, MemOpc, Chain }; > - SDNode *VLdA = CurDAG->getMachineNode(Opc, dl, ResTys, OpsA, 4); > + const SDValue OpsA[] = { MemAddr, MemUpdate, MemOpc, Align, > Chain }; > + SDNode *VLdA = CurDAG->getMachineNode(Opc, dl, ResTys, OpsA, 5); > Chain = SDValue(VLdA, NumVecs+1); > > // Load the odd subregs. > Opc = QOpcodes1[OpcodeIndex]; > - const SDValue OpsB[] = { SDValue(VLdA, NumVecs), MemUpdate, > MemOpc, Chain }; > - SDNode *VLdB = CurDAG->getMachineNode(Opc, dl, ResTys, OpsB, 4); > + const SDValue OpsB[] = { SDValue(VLdA, NumVecs), MemUpdate, > MemOpc, > + Align, Chain }; > + SDNode *VLdB = CurDAG->getMachineNode(Opc, dl, ResTys, OpsB, 5); > Chain = SDValue(VLdB, NumVecs+1); > > // Combine the even and odd subregs to produce the result. > @@ -1096,8 +1099,8 @@ > SDNode *N = Op.getNode(); > DebugLoc dl = N->getDebugLoc(); > > - SDValue MemAddr, MemUpdate, MemOpc; > - if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, > MemOpc)) > + SDValue MemAddr, MemUpdate, MemOpc, Align; > + if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, > MemOpc, Align)) > return NULL; > > SDValue Chain = N->getOperand(0); > @@ -1124,13 +1127,14 @@ > Ops.push_back(MemAddr); > Ops.push_back(MemUpdate); > Ops.push_back(MemOpc); > + Ops.push_back(Align); > > if (is64BitVector) { > unsigned Opc = DOpcodes[OpcodeIndex]; > for (unsigned Vec = 0; Vec < NumVecs; ++Vec) > Ops.push_back(N->getOperand(Vec+3)); > Ops.push_back(Chain); > - return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), > NumVecs+4); > + return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), > NumVecs+5); > } > > EVT RegVT = GetNEONSubregVT(VT); > @@ -1145,7 +1149,7 @@ > N->getOperand(Vec > +3))); > } > Ops.push_back(Chain); > - return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), > 8); > + return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), > 9); > } > > // Otherwise, quad registers are stored with two separate > instructions, > @@ -1161,18 +1165,18 @@ > Ops.push_back(Chain); > unsigned Opc = QOpcodes0[OpcodeIndex]; > SDNode *VStA = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType > (), > - MVT::Other, Ops.data(), > NumVecs+4); > + MVT::Other, Ops.data(), > NumVecs+5); > Chain = SDValue(VStA, 1); > > // Store the odd subregs. > Ops[0] = SDValue(VStA, 0); // MemAddr > for (unsigned Vec = 0; Vec < NumVecs; ++Vec) > - Ops[Vec+3] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, > RegVT, > + Ops[Vec+4] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, > RegVT, > N->getOperand(Vec+3)); > - Ops[NumVecs+3] = Chain; > + Ops[NumVecs+4] = Chain; > Opc = QOpcodes1[OpcodeIndex]; > SDNode *VStB = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType > (), > - MVT::Other, Ops.data(), > NumVecs+4); > + MVT::Other, Ops.data(), > NumVecs+5); > Chain = SDValue(VStB, 1); > ReplaceUses(SDValue(N, 0), Chain); > return NULL; > @@ -1186,8 +1190,8 @@ > SDNode *N = Op.getNode(); > DebugLoc dl = N->getDebugLoc(); > > - SDValue MemAddr, MemUpdate, MemOpc; > - if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, > MemOpc)) > + SDValue MemAddr, MemUpdate, MemOpc, Align; > + if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, > MemOpc, Align)) > return NULL; > > SDValue Chain = N->getOperand(0); > @@ -1224,6 +1228,7 @@ > Ops.push_back(MemAddr); > Ops.push_back(MemUpdate); > Ops.push_back(MemOpc); > + Ops.push_back(Align); > > unsigned Opc = 0; > if (is64BitVector) { > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=86404&r1=86403&r2=86404&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Sat Nov 7 15:25:39 2009 > @@ -340,9 +340,9 @@ > // addrmode6 := reg with optional writeback > // > def addrmode6 : Operand, > - ComplexPattern { > + ComplexPattern { > let PrintMethod = "printAddrMode6Operand"; > - let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm); > + let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm); > } > > // addrmodepc := pc + reg > > Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=86404&r1=86403&r2=86404&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Sat Nov > 7 15:25:39 2009 > @@ -638,9 +638,17 @@ > const MachineOperand &MO1 = MI->getOperand(Op); > const MachineOperand &MO2 = MI->getOperand(Op+1); > const MachineOperand &MO3 = MI->getOperand(Op+2); > + const MachineOperand &MO4 = MI->getOperand(Op+3); > > - // FIXME: No support yet for specifying alignment. > - O << "[" << getRegisterName(MO1.getReg()) << "]"; > + O << "[" << getRegisterName(MO1.getReg()); > + if (MO4.getImm()) { > + if (Subtarget->isTargetDarwin()) > + O << ", :"; > + else > + O << " @"; > + O << MO4.getImm(); > + } > + O << "]"; > > if (ARM_AM::getAM6WBFlag(MO3.getImm())) { > if (MO2.getReg() == 0) > > Modified: llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp?rev=86404&r1=86403&r2=86404&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp (original) > +++ llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp Sat Nov 7 > 15:25:39 2009 > @@ -177,20 +177,20 @@ > case ARM::VST2LNd8: > case ARM::VST2LNd16: > case ARM::VST2LNd32: > - FirstOpnd = 3; > + FirstOpnd = 4; > NumRegs = 2; > return true; > > case ARM::VST2q8: > case ARM::VST2q16: > case ARM::VST2q32: > - FirstOpnd = 3; > + FirstOpnd = 4; > NumRegs = 4; > return true; > > case ARM::VST2LNq16a: > case ARM::VST2LNq32a: > - FirstOpnd = 3; > + FirstOpnd = 4; > NumRegs = 2; > Offset = 0; > Stride = 2; > @@ -198,7 +198,7 @@ > > case ARM::VST2LNq16b: > case ARM::VST2LNq32b: > - FirstOpnd = 3; > + FirstOpnd = 4; > NumRegs = 2; > Offset = 1; > Stride = 2; > @@ -211,14 +211,14 @@ > case ARM::VST3LNd8: > case ARM::VST3LNd16: > case ARM::VST3LNd32: > - FirstOpnd = 3; > + FirstOpnd = 4; > NumRegs = 3; > return true; > > case ARM::VST3q8a: > case ARM::VST3q16a: > case ARM::VST3q32a: > - FirstOpnd = 4; > + FirstOpnd = 5; > NumRegs = 3; > Offset = 0; > Stride = 2; > @@ -227,7 +227,7 @@ > case ARM::VST3q8b: > case ARM::VST3q16b: > case ARM::VST3q32b: > - FirstOpnd = 4; > + FirstOpnd = 5; > NumRegs = 3; > Offset = 1; > Stride = 2; > @@ -235,7 +235,7 @@ > > case ARM::VST3LNq16a: > case ARM::VST3LNq32a: > - FirstOpnd = 3; > + FirstOpnd = 4; > NumRegs = 3; > Offset = 0; > Stride = 2; > @@ -243,7 +243,7 @@ > > case ARM::VST3LNq16b: > case ARM::VST3LNq32b: > - FirstOpnd = 3; > + FirstOpnd = 4; > NumRegs = 3; > Offset = 1; > Stride = 2; > @@ -256,14 +256,14 @@ > case ARM::VST4LNd8: > case ARM::VST4LNd16: > case ARM::VST4LNd32: > - FirstOpnd = 3; > + FirstOpnd = 4; > NumRegs = 4; > return true; > > case ARM::VST4q8a: > case ARM::VST4q16a: > case ARM::VST4q32a: > - FirstOpnd = 4; > + FirstOpnd = 5; > NumRegs = 4; > Offset = 0; > Stride = 2; > @@ -272,7 +272,7 @@ > case ARM::VST4q8b: > case ARM::VST4q16b: > case ARM::VST4q32b: > - FirstOpnd = 4; > + FirstOpnd = 5; > NumRegs = 4; > Offset = 1; > Stride = 2; > @@ -280,7 +280,7 @@ > > case ARM::VST4LNq16a: > case ARM::VST4LNq32a: > - FirstOpnd = 3; > + FirstOpnd = 4; > NumRegs = 4; > Offset = 0; > Stride = 2; > @@ -288,7 +288,7 @@ > > case ARM::VST4LNq16b: > case ARM::VST4LNq32b: > - FirstOpnd = 3; > + FirstOpnd = 4; > NumRegs = 4; > Offset = 1; > Stride = 2; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Tue Nov 10 03:32:10 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 10 Nov 2009 09:32:10 -0000 Subject: [llvm-commits] [llvm] r86681 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200911100932.nAA9WBrd009117@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 10 03:32:10 2009 New Revision: 86681 URL: http://llvm.org/viewvc/llvm-project?rev=86681&view=rev Log: Add brackets to make gcc-4.4 happy. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=86681&r1=86680&r2=86681&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Nov 10 03:32:10 2009 @@ -8262,9 +8262,9 @@ // expression tree to something weird like i93 unless the source is also // strange. if (!isa(SrcI->getType()) || - ShouldChangeType(SrcI->getType(), DestTy, TD) && - CanEvaluateInDifferentType(SrcI, DestTy, - CI.getOpcode(), NumCastsRemoved)) { + (ShouldChangeType(SrcI->getType(), DestTy, TD) && + CanEvaluateInDifferentType(SrcI, DestTy, + CI.getOpcode(), NumCastsRemoved))) { // If this cast is a truncate, evaluting in a different type always // eliminates the cast, so it is always a win. If this is a zero-extension, // we need to do an AND to maintain the clear top-part of the computation, From baldrick at free.fr Tue Nov 10 04:25:00 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 10 Nov 2009 10:25:00 -0000 Subject: [llvm-commits] [dragonegg] r86682 - in /dragonegg/trunk: llvm-convert.cpp llvm-internal.h Message-ID: <200911101025.nAAAP1HS011382@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 10 04:24:57 2009 New Revision: 86682 URL: http://llvm.org/viewvc/llvm-project?rev=86682&view=rev Log: It is important for Ada to get rid of trampolines wherever possible. Unfortunately the optimizers have a hard time doing this. Help them out by using llvm.invariant.start to mark the trampoline storage as being constant after the initial write. The llvm.invariant.start/end intrinsics are annoyingly hard to use. There needs to be an llvm.invariant.end call because otherwise the llvm.invariant.start call will be deleted being readonly. The call to llvm.invariant.start needs to dominate the end call, which is hard to achieve cheaply unless the start call is in the entry block. This is the reason this patch pushes the trampoline initialization into the entry block. The region lasts until the end of the function, which means calling llvm.invariant.end at every possible exit point of the program. This is impossible in general, since potentially the optimizers may discover that some call in the program does not return, at which point they may discard vast amounts of unreachable code which might include any llvm.invariant.end calls, at which point the start calls will be deleted too being readonly with no uses. Modified: dragonegg/trunk/llvm-convert.cpp dragonegg/trunk/llvm-internal.h Modified: dragonegg/trunk/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=86682&r1=86681&r2=86682&view=diff ============================================================================== --- dragonegg/trunk/llvm-convert.cpp (original) +++ dragonegg/trunk/llvm-convert.cpp Tue Nov 10 04:24:57 2009 @@ -763,6 +763,26 @@ typedef SmallVector, 8> TreeVector; typedef SmallVector, 8> ValueVector; +/// EndInvariantRegions - Output a call to llvm.invariant.end for each call +/// to llvm.invariant.start recorded in InvariantRegions. +void TreeToLLVM::EndInvariantRegions() { + if (InvariantRegions.empty()) + return; + + Value *Ops[3]; + Value *IEnd = Intrinsic::getDeclaration(TheModule,Intrinsic::invariant_end); + for (unsigned i = 0, e = InvariantRegions.size(); i < e; ++i) { + CallInst *CI = InvariantRegions[i]; + Ops[0] = CI; + Ops[1] = CI->getOperand(1); + Ops[2] = CI->getOperand(2); + Builder.CreateCall(IEnd, Ops, Ops + 3); + } + + // Do not clear out InvariantRegions in case the function has multiple exits: + // we need to output calls to llvm.invariant.end before each one. +} + /// PopulatePhiNodes - Populate generated phi nodes with their operands. void TreeToLLVM::PopulatePhiNodes() { PredVector Predecessors; @@ -929,6 +949,9 @@ TheDebugInfo->EmitStopPoint(Fn, Builder.GetInsertBlock(), Builder); TheDebugInfo->EmitFunctionEnd(Builder.GetInsertBlock(), true); } + + EndInvariantRegions(); + if (RetVals.empty()) Builder.CreateRetVoid(); else if (RetVals.size() == 1 && RetVals[0]->getType() == Fn->getReturnType()){ @@ -2105,6 +2128,7 @@ if (UnwindBB) { CreateExceptionValues(); EmitBlock(UnwindBB); + EndInvariantRegions(); abort();//FIXME //FIXME // Fetch and store exception handler. //FIXME Value *Arg = Builder.CreateLoad(ExceptionValue, "eh_ptr"); @@ -2543,6 +2567,7 @@ // after the function to prevent LLVM from thinking that control flow will // fall into the subsequent block. if (gimple_call_flags(stmt) & ECF_NORETURN) { + EndInvariantRegions(); Builder.CreateUnreachable(); EmitBlock(BasicBlock::Create(Context)); } @@ -4613,6 +4638,7 @@ case BUILT_IN_TRAP: Builder.CreateCall(Intrinsic::getDeclaration(TheModule, Intrinsic::trap)); // Emit an explicit unreachable instruction. + EndInvariantRegions(); Builder.CreateUnreachable(); EmitBlock(BasicBlock::Create(Context)); return true; @@ -5459,6 +5485,7 @@ Args.push_back(Handler); Builder.CreateCall(Intrinsic::getDeclaration(TheModule, IID), Args.begin(), Args.end()); + EndInvariantRegions(); Result = Builder.CreateUnreachable(); EmitBlock(BasicBlock::Create(Context)); @@ -5672,6 +5699,26 @@ // is called. static const Type *VPTy = Type::getInt8PtrTy(Context); + // In order to simplify the use of llvm.invariant.start/end, generate the + // trampoline initialization code in the entry block. + BasicBlock *EntryBlock = Fn->begin(); + + // Note the current builder position. + BasicBlock *SavedInsertBB = Builder.GetInsertBlock(); + BasicBlock::iterator SavedInsertPoint = Builder.GetInsertPoint(); + + // Pop the entry block terminator. There may not be a terminator if the entry + // block was not yet finished. + Instruction *Terminator = EntryBlock->getTerminator(); + assert(((SavedInsertBB != EntryBlock && Terminator) || + (SavedInsertPoint == EntryBlock->end() && !Terminator)) && + "Insertion point doesn't make sense!"); + if (Terminator) + Terminator->removeFromParent(); + + // Point the builder at the end of the entry block. + Builder.SetInsertPoint(EntryBlock); + // Create a stack temporary to hold the trampoline machine code. const Type *TrampType = ArrayType::get(Type::getInt8Ty(Context), TRAMPOLINE_SIZE); @@ -5703,6 +5750,22 @@ unsigned Align = TYPE_ALIGN(TREE_TYPE(TREE_TYPE(gimple_call_arg(stmt, 0))))/8; Store->setAlignment(Align); + // The GCC trampoline storage is constant from this point on. Tell this to + // the optimizers. + Intr = Intrinsic::getDeclaration(TheModule, Intrinsic::invariant_start); + Ops[0] = ConstantInt::get(Type::getInt64Ty(Context), TRAMPOLINE_SIZE); + Ops[1] = Builder.CreateBitCast(Tramp, VPTy); + CallInst *InvStart = Builder.CreateCall(Intr, Ops, Ops + 2); + InvariantRegions.push_back(InvStart); + + // Restore the entry block terminator. + if (Terminator) + EntryBlock->getInstList().push_back(Terminator); + + // Restore the builder insertion point. + if (SavedInsertBB != EntryBlock) + Builder.SetInsertPoint(SavedInsertBB, SavedInsertPoint); + return true; } Modified: dragonegg/trunk/llvm-internal.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-internal.h?rev=86682&r1=86681&r2=86682&view=diff ============================================================================== --- dragonegg/trunk/llvm-internal.h (original) +++ dragonegg/trunk/llvm-internal.h Tue Nov 10 04:24:57 2009 @@ -357,6 +357,10 @@ /// LocalDecls - Map from local declarations to their associated LLVM values. DenseMap > LocalDecls; + /// InvariantRegions - Calls to llvm.invariant.start for which a corresponding + /// call to llvm.invariant.end needs to be generated at function exit points. + SmallVector InvariantRegions; + /// PendingPhis - Phi nodes which have not yet been populated with operands. SmallVector PendingPhis; @@ -469,11 +473,15 @@ /// StartFunctionBody - Start the emission of 'fndecl', outputing all /// declarations for parameters and setting things up. void StartFunctionBody(); - + /// FinishFunctionBody - Once the body of the function has been emitted, this /// cleans up and returns the result function. Function *FinishFunctionBody(); + /// EndInvariantRegions - Output a call to llvm.invariant.end for each call + /// of llvm.invariant.start recorded in InvariantRegions. + void EndInvariantRegions(); + /// PopulatePhiNodes - Populate generated phi nodes with their operands. void PopulatePhiNodes(); From baldrick at free.fr Tue Nov 10 07:49:51 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 10 Nov 2009 13:49:51 -0000 Subject: [llvm-commits] [llvm] r86683 - in /llvm/trunk: lib/Transforms/Scalar/DeadStoreElimination.cpp test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll Message-ID: <200911101349.nAADnp5u018505@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 10 07:49:50 2009 New Revision: 86683 URL: http://llvm.org/viewvc/llvm-project?rev=86683&view=rev Log: Teach DSE to eliminate useless trampolines. Added: llvm/trunk/test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=86683&r1=86682&r2=86683&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Tue Nov 10 07:49:50 2009 @@ -87,13 +87,13 @@ switch (II->getIntrinsicID()) { default: return false; case Intrinsic::memset: case Intrinsic::memmove: case Intrinsic::memcpy: - case Intrinsic::lifetime_end: return true; + case Intrinsic::init_trampoline: case Intrinsic::lifetime_end: return true; } } return false; } -/// isElidable - If the memory this instruction and the memory it writes to is +/// isElidable - If the value of this instruction and the memory it writes to is /// unused, may we delete this instrtction? static bool isElidable(Instruction *I) { assert(doesClobberMemory(I)); @@ -111,8 +111,15 @@ return SI->getPointerOperand(); if (MemIntrinsic *MI = dyn_cast(I)) return MI->getOperand(1); - assert(cast(I)->getIntrinsicID() == Intrinsic::lifetime_end); - return cast(I)->getOperand(2); + IntrinsicInst *II = cast(I); + switch (II->getIntrinsicID()) { + default: + assert(false && "Unexpected intrinsic!"); + case Intrinsic::init_trampoline: + return II->getOperand(1); + case Intrinsic::lifetime_end: + return II->getOperand(2); + } } /// getStoreSize - Return the length in bytes of the write by the clobbering @@ -129,8 +136,14 @@ Len = MI->getLength(); } else { IntrinsicInst *II = cast(I); - assert(II->getIntrinsicID() == Intrinsic::lifetime_end); - Len = II->getOperand(0); + switch (II->getIntrinsicID()) { + default: + assert(false && "Unexpected intrinsic!"); + case Intrinsic::init_trampoline: + return -1u; + case Intrinsic::lifetime_end: + Len = II->getOperand(0); + } } if (ConstantInt *LenCI = dyn_cast(Len)) if (!LenCI->isAllOnesValue()) Added: llvm/trunk/test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll?rev=86683&view=auto ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll (added) +++ llvm/trunk/test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll Tue Nov 10 07:49:50 2009 @@ -0,0 +1,16 @@ +; RUN: opt -S -dse < %s | FileCheck %s + +declare i8* @llvm.init.trampoline(i8*, i8*, i8*) + +declare void @f() + +define void @unused_trampoline() { +; CHECK: @unused_trampoline + %storage = alloca [10 x i8], align 16 ; <[10 x i8]*> [#uses=1] +; CHECK-NOT: alloca + %cast = getelementptr [10 x i8]* %storage, i32 0, i32 0 ; [#uses=1] + %tramp = call i8* @llvm.init.trampoline( i8* %cast, i8* bitcast (void ()* @f to i8*), i8* null ) ; [#uses=1] +; CHECK-NOT: trampoline + ret void +; CHECK: ret void +} From dgregor at apple.com Tue Nov 10 09:30:33 2009 From: dgregor at apple.com (Douglas Gregor) Date: Tue, 10 Nov 2009 15:30:33 -0000 Subject: [llvm-commits] [llvm] r86684 - /llvm/trunk/cmake/modules/AddLLVM.cmake Message-ID: <200911101530.nAAFUY57021601@zion.cs.uiuc.edu> Author: dgregor Date: Tue Nov 10 09:30:33 2009 New Revision: 86684 URL: http://llvm.org/viewvc/llvm-project?rev=86684&view=rev Log: CMake: Add Darwin-specific linker flags for building loadable modules Modified: llvm/trunk/cmake/modules/AddLLVM.cmake Modified: llvm/trunk/cmake/modules/AddLLVM.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/AddLLVM.cmake?rev=86684&r1=86683&r2=86684&view=diff ============================================================================== --- llvm/trunk/cmake/modules/AddLLVM.cmake (original) +++ llvm/trunk/cmake/modules/AddLLVM.cmake Tue Nov 10 09:30:33 2009 @@ -27,10 +27,16 @@ message(STATUS "Loadable modules not supported on this platform. ${name} ignored.") else() - set(BUILD_SHARED_LIBS ON) llvm_process_sources( ALL_FILES ${ARGN} ) add_library( ${name} MODULE ${ALL_FILES} ) set_target_properties( ${name} PROPERTIES PREFIX "" ) + + if (APPLE) + # Darwin-specific linker flags for loadable modules. + set_target_properties(${name} PROPERTIES + LINK_FLAGS "-Wl,-flat_namespace -Wl,-undefined -Wl,suppress") + endif() + install(TARGETS ${name} LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}) From johnny.chen at apple.com Tue Nov 10 10:52:26 2009 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 10 Nov 2009 08:52:26 -0800 Subject: [llvm-commits] Question on emitLoadStoreInstruction() of ARMCodeEmitter.cpp In-Reply-To: <1098E54E-0B98-4E3F-BE64-25CE8A9883F4@apple.com> References: <7A82351B-4D89-4F9A-A90F-D546B6F28832@apple.com> <1098E54E-0B98-4E3F-BE64-25CE8A9883F4@apple.com> Message-ID: <8F65E3F1-9F95-469F-BA31-0D24BDBEB307@apple.com> Hi Evan, Thanks for the reply. But from the emitLoadStoreInstruction() code inspection, it looks like it special-cases for operand 0 to be base_wb and operand 1 to be dst, which is not the correct order. It should have been operand 0 as dst and operand 1 as base_wb? Johnny On Nov 9, 2009, at 10:38 PM, Evan Cheng wrote: > > On Nov 9, 2009, at 5:46 PM, Johnny Chen wrote: > >> >> Hi, >> >> I have a question wrt the following fragment of code: >> >> // Operand 0 of a pre- and post-indexed store is the address base >> // writeback. Skip it. >> bool Skipped = false; >> if (IsPrePost && Form == ARMII::StFrm) { >> ++OpIdx; >> Skipped = true; >> } >> >> // Set first operand >> if (ImplicitRd) >> // Special handling for implicit use (e.g. PC). >> Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd) >> << ARMII::RegRdShift); >> else >> Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift; >> >> and from the Record definition of LDRB_POST: >> >> def LDRB_POST { // Instruction InstARM I AI2ldbpo >> field bits<32> Inst = { ?, ?, ?, ?, 0, 1, ?, 0, ?, 1, 0, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? }; >> string Namespace = "ARM"; >> dag OutOperandList = (outs GPR:$dst, GPR:$base_wb); >> dag InOperandList = (ins GPR:$base, am2offset:$offset, pred:$p); >> string AsmString = "ldrb${p} $dst, [$base], $offset"; >> >> it looks like the processing of "address base writeback" should happen after the processing of RegRd, >> if the ordering of OutOperandList followed by InOperandList is to be observed. Is my understanding of >> the ordering of the MachineOperands correct? > > Right. Defs comes first followed by uses. > >> >> If this is the case, then there could be some bug in the codegen which compensates for the incorrect >> ordering/processing of base_writeback/dst? > > No. It's fine. The second operand is base_wb, base will be skipped. > > Evan > >> >> Thanks. >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From sabre at nondot.org Tue Nov 10 10:56:24 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 08:56:24 -0800 Subject: [llvm-commits] [llvm] r86670 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/cast-mul-select.ll test/Transforms/InstCombine/cast.ll In-Reply-To: <4AF9278A.6010803@free.fr> References: <200911100723.nAA7Nc5X022955@zion.cs.uiuc.edu> <4AF9278A.6010803@free.fr> Message-ID: On Nov 10, 2009, at 12:42 AM, Duncan Sands wrote: > Hi Chris, > >> + // If we don't have TD, we don't know if the source/dest are >> legal. >> + if (!TD) return false; > > I guess it is reasonable to assume that if the number of bits is not > divisible by 8 then it is illegal. That said, would adding this case > buy much? I'm not sure what you mean. Do you mean in the case when TD is not available? If so, doing any transformation is not safe, because you might be changing away from a legal type and not know it. -Chris From sabre at nondot.org Tue Nov 10 11:00:48 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 17:00:48 -0000 Subject: [llvm-commits] [llvm] r86689 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200911101700.nAAH0mUc024708@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 11:00:47 2009 New Revision: 86689 URL: http://llvm.org/viewvc/llvm-project?rev=86689&view=rev Log: clarify logic. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=86689&r1=86688&r2=86689&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Nov 10 11:00:47 2009 @@ -8261,10 +8261,10 @@ // Only do this if the dest type is a simple type, don't convert the // expression tree to something weird like i93 unless the source is also // strange. - if (!isa(SrcI->getType()) || - (ShouldChangeType(SrcI->getType(), DestTy, TD) && - CanEvaluateInDifferentType(SrcI, DestTy, - CI.getOpcode(), NumCastsRemoved))) { + if ((isa(DestTy) || + ShouldChangeType(SrcI->getType(), DestTy, TD)) && + CanEvaluateInDifferentType(SrcI, DestTy, + CI.getOpcode(), NumCastsRemoved)) { // If this cast is a truncate, evaluting in a different type always // eliminates the cast, so it is always a win. If this is a zero-extension, // we need to do an AND to maintain the clear top-part of the computation, From evan.cheng at apple.com Tue Nov 10 11:02:44 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 10 Nov 2009 09:02:44 -0800 Subject: [llvm-commits] Question on emitLoadStoreInstruction() of ARMCodeEmitter.cpp In-Reply-To: <8F65E3F1-9F95-469F-BA31-0D24BDBEB307@apple.com> References: <7A82351B-4D89-4F9A-A90F-D546B6F28832@apple.com> <1098E54E-0B98-4E3F-BE64-25CE8A9883F4@apple.com> <8F65E3F1-9F95-469F-BA31-0D24BDBEB307@apple.com> Message-ID: <16971515-6B3C-484C-82A8-9CC4C5B2FC50@apple.com> On Nov 10, 2009, at 8:52 AM, Johnny Chen wrote: > Hi Evan, > > Thanks for the reply. > But from the emitLoadStoreInstruction() code inspection, it looks > like it special-cases for > operand 0 to be base_wb and operand 1 to be dst, which is not the > correct order. > It should have been operand 0 as dst and operand 1 as base_wb? I don't see it. I haven't been able to test the JIT for a long time but this code used to work fine. Is something broken? Evan > > Johnny > > On Nov 9, 2009, at 10:38 PM, Evan Cheng wrote: > >> >> On Nov 9, 2009, at 5:46 PM, Johnny Chen wrote: >> >>> >>> Hi, >>> >>> I have a question wrt the following fragment of code: >>> >>> // Operand 0 of a pre- and post-indexed store is the address base >>> // writeback. Skip it. >>> bool Skipped = false; >>> if (IsPrePost && Form == ARMII::StFrm) { >>> ++OpIdx; >>> Skipped = true; >>> } >>> >>> // Set first operand >>> if (ImplicitRd) >>> // Special handling for implicit use (e.g. PC). >>> Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd) >>> << ARMII::RegRdShift); >>> else >>> Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift; >>> >>> and from the Record definition of LDRB_POST: >>> >>> def LDRB_POST { // Instruction InstARM I AI2ldbpo >>> field bits<32> Inst = { ?, ?, ?, ?, 0, 1, ?, 0, ?, 1, 0, >>> 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? }; >>> string Namespace = "ARM"; >>> dag OutOperandList = (outs GPR:$dst, GPR:$base_wb); >>> dag InOperandList = (ins GPR:$base, am2offset:$offset, pred:$p); >>> string AsmString = "ldrb${p} $dst, [$base], $offset"; >>> >>> it looks like the processing of "address base writeback" should >>> happen after the processing of RegRd, >>> if the ordering of OutOperandList followed by InOperandList is to >>> be observed. Is my understanding of >>> the ordering of the MachineOperands correct? >> >> Right. Defs comes first followed by uses. >> >>> >>> If this is the case, then there could be some bug in the codegen >>> which compensates for the incorrect >>> ordering/processing of base_writeback/dst? >> >> No. It's fine. The second operand is base_wb, base will be skipped. >> >> Evan >> >>> >>> Thanks. >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > From baldrick at free.fr Tue Nov 10 11:09:44 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 10 Nov 2009 18:09:44 +0100 Subject: [llvm-commits] [llvm] r86670 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/cast-mul-select.ll test/Transforms/InstCombine/cast.ll In-Reply-To: References: <200911100723.nAA7Nc5X022955@zion.cs.uiuc.edu> <4AF9278A.6010803@free.fr> Message-ID: <4AF99E58.8050204@free.fr> Chris Lattner wrote: > > On Nov 10, 2009, at 12:42 AM, Duncan Sands wrote: > >> Hi Chris, >> >>> + // If we don't have TD, we don't know if the source/dest are legal. >>> + if (!TD) return false; >> >> I guess it is reasonable to assume that if the number of bits is not >> divisible by 8 then it is illegal. That said, would adding this case >> buy much? > > I'm not sure what you mean. Do you mean in the case when TD is not > available? If so, doing any transformation is not safe, because you > might be changing away from a legal type and not know it. What I'm saying is that we can be pretty sure that i44 is illegal, even if there is no TD. Thus i44 -> i32 could be done even without TD. Ciao, Duncan. From johnny.chen at apple.com Tue Nov 10 11:10:47 2009 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 10 Nov 2009 09:10:47 -0800 Subject: [llvm-commits] Question on emitLoadStoreInstruction() of ARMCodeEmitter.cpp In-Reply-To: <16971515-6B3C-484C-82A8-9CC4C5B2FC50@apple.com> References: <7A82351B-4D89-4F9A-A90F-D546B6F28832@apple.com> <1098E54E-0B98-4E3F-BE64-25CE8A9883F4@apple.com> <8F65E3F1-9F95-469F-BA31-0D24BDBEB307@apple.com> <16971515-6B3C-484C-82A8-9CC4C5B2FC50@apple.com> Message-ID: <3B0B67C8-95EC-4C4D-B3FE-5996155C1710@apple.com> Hi Evan, I think I have been confusing load with store for this message thread. Thanks. On Nov 10, 2009, at 9:02 AM, Evan Cheng wrote: > > On Nov 10, 2009, at 8:52 AM, Johnny Chen wrote: > >> Hi Evan, >> >> Thanks for the reply. >> But from the emitLoadStoreInstruction() code inspection, it looks like it special-cases for >> operand 0 to be base_wb and operand 1 to be dst, which is not the correct order. >> It should have been operand 0 as dst and operand 1 as base_wb? > > I don't see it. I haven't been able to test the JIT for a long time but this code used to work fine. Is something broken? > > Evan > >> >> Johnny >> >> On Nov 9, 2009, at 10:38 PM, Evan Cheng wrote: >> >>> >>> On Nov 9, 2009, at 5:46 PM, Johnny Chen wrote: >>> >>>> >>>> Hi, >>>> >>>> I have a question wrt the following fragment of code: >>>> >>>> // Operand 0 of a pre- and post-indexed store is the address base >>>> // writeback. Skip it. >>>> bool Skipped = false; >>>> if (IsPrePost && Form == ARMII::StFrm) { >>>> ++OpIdx; >>>> Skipped = true; >>>> } >>>> >>>> // Set first operand >>>> if (ImplicitRd) >>>> // Special handling for implicit use (e.g. PC). >>>> Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd) >>>> << ARMII::RegRdShift); >>>> else >>>> Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift; >>>> >>>> and from the Record definition of LDRB_POST: >>>> >>>> def LDRB_POST { // Instruction InstARM I AI2ldbpo >>>> field bits<32> Inst = { ?, ?, ?, ?, 0, 1, ?, 0, ?, 1, 0, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? }; >>>> string Namespace = "ARM"; >>>> dag OutOperandList = (outs GPR:$dst, GPR:$base_wb); >>>> dag InOperandList = (ins GPR:$base, am2offset:$offset, pred:$p); >>>> string AsmString = "ldrb${p} $dst, [$base], $offset"; >>>> >>>> it looks like the processing of "address base writeback" should happen after the processing of RegRd, >>>> if the ordering of OutOperandList followed by InOperandList is to be observed. Is my understanding of >>>> the ordering of the MachineOperands correct? >>> >>> Right. Defs comes first followed by uses. >>> >>>> >>>> If this is the case, then there could be some bug in the codegen which compensates for the incorrect >>>> ordering/processing of base_writeback/dst? >>> >>> No. It's fine. The second operand is base_wb, base will be skipped. >>> >>> Evan >>> >>>> >>>> Thanks. >>>> _______________________________________________ >>>> llvm-commits mailing list >>>> llvm-commits at cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>> >> > From kennethuil at gmail.com Tue Nov 10 11:15:39 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Tue, 10 Nov 2009 11:15:39 -0600 Subject: [llvm-commits] [llvm] r86670 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/cast-mul-select.ll test/Transforms/InstCombine/cast.ll In-Reply-To: <4AF99E58.8050204@free.fr> References: <200911100723.nAA7Nc5X022955@zion.cs.uiuc.edu> <4AF9278A.6010803@free.fr> <4AF99E58.8050204@free.fr> Message-ID: <400d33ea0911100915t21977367l67b85b47ba01d01f@mail.gmail.com> On Tue, Nov 10, 2009 at 11:09 AM, Duncan Sands wrote: > Chris Lattner wrote: >> >> On Nov 10, 2009, at 12:42 AM, Duncan Sands wrote: >> >>> Hi Chris, >>> >>>> + ?// If we don't have TD, we don't know if the source/dest are legal. >>>> + ?if (!TD) return false; >>> >>> I guess it is reasonable to assume that if the number of bits is not >>> divisible by 8 then it is illegal. ?That said, would adding this case >>> buy much? >> >> I'm not sure what you mean. ?Do you mean in the case when TD is not >> available? ?If so, doing any transformation is not safe, because you >> might be changing away from a legal type and not know it. > > What I'm saying is that we can be pretty sure that i44 is illegal, even if > there is no TD. ?Thus i44 -> i32 could be done even without TD. but what about i44->i64? Or i44->i128? If you want the transformation to take target specific stuff into account, feed it target data. If you don't, you should only get target independent transformations. You can always run it again with target data in a target-deployment step... From sabre at nondot.org Tue Nov 10 11:31:25 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 09:31:25 -0800 Subject: [llvm-commits] [llvm] r86670 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/cast-mul-select.ll test/Transforms/InstCombine/cast.ll In-Reply-To: <4AF99E58.8050204@free.fr> References: <200911100723.nAA7Nc5X022955@zion.cs.uiuc.edu> <4AF9278A.6010803@free.fr> <4AF99E58.8050204@free.fr> Message-ID: On Nov 10, 2009, at 9:09 AM, Duncan Sands wrote: > Chris Lattner wrote: >> On Nov 10, 2009, at 12:42 AM, Duncan Sands wrote: >>> Hi Chris, >>> >>>> + // If we don't have TD, we don't know if the source/dest are >>>> legal. >>>> + if (!TD) return false; >>> >>> I guess it is reasonable to assume that if the number of bits is not >>> divisible by 8 then it is illegal. That said, would adding this >>> case >>> buy much? >> I'm not sure what you mean. Do you mean in the case when TD is not >> available? If so, doing any transformation is not safe, because >> you might be changing away from a legal type and not know it. > > What I'm saying is that we can be pretty sure that i44 is illegal, > even if > there is no TD. Thus i44 -> i32 could be done even without TD. I don't think it's worth it to worry about this. Particularly when dealing with funny sized integers, doing 'safe' obviously profitable transformations only seems prudent. -Chris From daniel at zuster.org Tue Nov 10 12:20:16 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 10 Nov 2009 18:20:16 -0000 Subject: [llvm-commits] [zorg] r86692 - /zorg/trunk/zorg/buildbot/builders/LLVMGCCBuilder.py Message-ID: <200911101820.nAAIKGo3027774@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 10 12:20:15 2009 New Revision: 86692 URL: http://llvm.org/viewvc/llvm-project?rev=86692&view=rev Log: Allow jobs to be specified as a property. Modified: zorg/trunk/zorg/buildbot/builders/LLVMGCCBuilder.py Modified: zorg/trunk/zorg/buildbot/builders/LLVMGCCBuilder.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/zorg/buildbot/builders/LLVMGCCBuilder.py?rev=86692&r1=86691&r2=86692&view=diff ============================================================================== --- zorg/trunk/zorg/buildbot/builders/LLVMGCCBuilder.py (original) +++ zorg/trunk/zorg/buildbot/builders/LLVMGCCBuilder.py Tue Nov 10 12:20:15 2009 @@ -84,7 +84,7 @@ # Build llvm (stage 1). f.addStep(WarningCountingShellCommand(name = "compile.llvm.stage1", - command = "nice -n 10 make -j%d" % jobs, + command = WithProperties("nice -n 10 make -j%s" % jobs), haltOnFailure = True, description=["compile", "llvm", @@ -130,7 +130,7 @@ # Build llvm-gcc. f.addStep(WarningCountingShellCommand(name="compile.llvm-gcc.stage1", - command="nice -n 10 make -j%d" % jobs, + command = WithProperties("nice -n 10 make -j%s" % jobs), haltOnFailure=True, description=["compile", "llvm-gcc"], @@ -185,7 +185,7 @@ # Build LLVM (stage 2). f.addStep(WarningCountingShellCommand(name = "compile.llvm.stage2", - command = "nice -n 10 make -j%d" % jobs, + command = WithProperties("nice -n 10 make -j%s" % jobs), haltOnFailure = True, description=["compile", "llvm", @@ -226,7 +226,7 @@ # Build llvm-gcc (stage 2). f.addStep(WarningCountingShellCommand(name="compile.llvm-gcc.stage2", - command="nice -n 10 make -j%d" % jobs, + command=WithProperties("nice -n 10 make -j%s" % jobs), haltOnFailure=True, description=["compile", "llvm-gcc", From daniel at zuster.org Tue Nov 10 12:21:22 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 10 Nov 2009 18:21:22 -0000 Subject: [llvm-commits] [zorg] r86693 - /zorg/trunk/zorg/buildbot/util/InformativeMailNotifier.py Message-ID: <200911101821.nAAILMko027833@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 10 12:21:22 2009 New Revision: 86693 URL: http://llvm.org/viewvc/llvm-project?rev=86693&view=rev Log: Fix bug in InformativeMailNotifier compare routine that ended up comapring a bound method, which led to an infinite loop. Modified: zorg/trunk/zorg/buildbot/util/InformativeMailNotifier.py Modified: zorg/trunk/zorg/buildbot/util/InformativeMailNotifier.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/zorg/buildbot/util/InformativeMailNotifier.py?rev=86693&r1=86692&r2=86693&view=diff ============================================================================== --- zorg/trunk/zorg/buildbot/util/InformativeMailNotifier.py (original) +++ zorg/trunk/zorg/buildbot/util/InformativeMailNotifier.py Tue Nov 10 12:21:22 2009 @@ -10,6 +10,10 @@ compare_attrs = (mail.MailNotifier.compare_attrs + ["num_lines", "only_failure_logs"]) + # Remove customMesg from the compare_attrs, that would lead to + # recursion, and is checked by the class test. + compare_attrs.remove("customMesg") + # FIXME: The customMessage interface is fairly inefficient, switch to # something new when it becomes available. From baldrick at free.fr Tue Nov 10 12:21:37 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 10 Nov 2009 18:21:37 -0000 Subject: [llvm-commits] [llvm] r86694 - /llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Message-ID: <200911101821.nAAILbbK027850@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 10 12:21:37 2009 New Revision: 86694 URL: http://llvm.org/viewvc/llvm-project?rev=86694&view=rev Log: Fix obvious typo. Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=86694&r1=86693&r2=86694&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Tue Nov 10 12:21:37 2009 @@ -142,7 +142,7 @@ case Intrinsic::init_trampoline: return -1u; case Intrinsic::lifetime_end: - Len = II->getOperand(0); + Len = II->getOperand(1); } } if (ConstantInt *LenCI = dyn_cast(Len)) From daniel at zuster.org Tue Nov 10 12:24:38 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 10 Nov 2009 18:24:38 -0000 Subject: [llvm-commits] [llvm] r86695 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200911101824.nAAIOcnH027959@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 10 12:24:37 2009 New Revision: 86695 URL: http://llvm.org/viewvc/llvm-project?rev=86695&view=rev Log: Add a monstrous hack to improve X86ISelDAGToDAG compile time. - Force NDEBUG on in any Release build. This drops the compile time to ~100s from ~600s, in Release mode. - This may just be a temporary workaround, I don't know the true nature of the gcc-4.2 compile time performance problem. Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=86695&r1=86694&r2=86695&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Nov 10 12:24:37 2009 @@ -12,6 +12,14 @@ // //===----------------------------------------------------------------------===// +// Force NDEBUG on in any optimized build on Darwin. +// +// FIXME: This is a huge hack, to work around ridiculously awful compile times +// on this file with gcc-4.2 on Darwin, in Release mode. +#if defined(__APPLE__) && defined(__OPTIMIZE__) && !defined(NDEBUG) +#define NDEBUG +#endif + #define DEBUG_TYPE "x86-isel" #include "X86.h" #include "X86InstrBuilder.h" From kennethuil at gmail.com Tue Nov 10 12:32:41 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Tue, 10 Nov 2009 12:32:41 -0600 Subject: [llvm-commits] [llvm] r86695 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp In-Reply-To: <200911101824.nAAIOcnH027959@zion.cs.uiuc.edu> References: <200911101824.nAAIOcnH027959@zion.cs.uiuc.edu> Message-ID: <400d33ea0911101032o3157314exc5cc139b0ee8c4e1@mail.gmail.com> On Tue, Nov 10, 2009 at 12:24 PM, Daniel Dunbar wrote: > Author: ddunbar > Date: Tue Nov 10 12:24:37 2009 > New Revision: 86695 > > URL: http://llvm.org/viewvc/llvm-project?rev=86695&view=rev > Log: > Add a monstrous hack to improve X86ISelDAGToDAG compile time. > ?- Force NDEBUG on in any Release build. This drops the compile time to ~100s > ? from ~600s, in Release mode. > > ?- This may just be a temporary workaround, I don't know the true nature of the > ? gcc-4.2 compile time performance problem. > > Modified: > ? ?llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp > > Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=86695&r1=86694&r2=86695&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Nov 10 12:24:37 2009 > @@ -12,6 +12,14 @@ > ?// > ?//===----------------------------------------------------------------------===// > > +// Force NDEBUG on in any optimized build on Darwin. > +// > +// FIXME: This is a huge hack, to work around ridiculously awful compile times > +// on this file with gcc-4.2 on Darwin, in Release mode. > +#if defined(__APPLE__) && defined(__OPTIMIZE__) && !defined(NDEBUG) > +#define NDEBUG > +#endif > + > ?#define DEBUG_TYPE "x86-isel" > ?#include "X86.h" > ?#include "X86InstrBuilder.h" > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > gcc 4.3.2 on Linux x86 and gcc 3.4.4 on cygwin also take an awfully long time to compile that particularly long file. Is there something special about Darwin, or would that hack work safely on other platforms? From kennethuil at gmail.com Tue Nov 10 12:33:51 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Tue, 10 Nov 2009 12:33:51 -0600 Subject: [llvm-commits] [llvm] r86695 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp In-Reply-To: <400d33ea0911101033ra54a96dv4062cf8ad72b8353@mail.gmail.com> References: <200911101824.nAAIOcnH027959@zion.cs.uiuc.edu> <400d33ea0911101032o3157314exc5cc139b0ee8c4e1@mail.gmail.com> <400d33ea0911101033ra54a96dv4062cf8ad72b8353@mail.gmail.com> Message-ID: <400d33ea0911101033k786fbfd3ha4fd3c460d8201b3@mail.gmail.com> On Tue, Nov 10, 2009 at 12:33 PM, Kenneth Uildriks wrote: >> gcc 4.3.2 on Linux x86 and gcc 3.4.4 on cygwin also take an awfully >> long time to compile that particularly long file. ?Is there something >> special about Darwin, or would that hack work safely on other >> platforms? >> > > I meant to say, of course, that they take an awfully long time to > compile that particular file. > From grosbach at apple.com Tue Nov 10 13:11:36 2009 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 10 Nov 2009 19:11:36 -0000 Subject: [llvm-commits] [test-suite] r86698 - /test-suite/trunk/Makefile.programs Message-ID: <200911101911.nAAJBbEN029615@zion.cs.uiuc.edu> Author: grosbach Date: Tue Nov 10 13:11:36 2009 New Revision: 86698 URL: http://llvm.org/viewvc/llvm-project?rev=86698&view=rev Log: ARM/Thumb llcbeta Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=86698&r1=86697&r2=86698&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Tue Nov 10 13:11:36 2009 @@ -244,13 +244,11 @@ LLCBETAOPTION := -enable-sparc-v9-insts endif ifeq ($(ARCH),ARM) -LLCBETAOPTION := -arm-dynamic-stack-alignment -#-combiner-alias-analysis +LLCBETAOPTION := -combiner-alias-analysis #-schedule-livein-copies endif ifeq ($(ARCH),THUMB) -LLCBETAOPTION := -arm-dynamic-stack-alignment -#-combiner-alias-analysis +LLCBETAOPTION := -combiner-alias-analysis #-enable-thumb-reg-scavenging endif From vkutuzov at accesssoftek.com Tue Nov 10 13:18:45 2009 From: vkutuzov at accesssoftek.com (Viktor Kutuzov) Date: Tue, 10 Nov 2009 11:18:45 -0800 Subject: [llvm-commits] [PATCH] LTO code generator options References: <04F6B1512E264B27AEE607542FCDD113@andreic6e7fe55> Message-ID: <9C7CA4093A8F41D7AD156ED3CF854D17@andreic6e7fe55> Is this Ok to submit? Best regards, Viktor ----- Original Message ----- From: "Viktor Kutuzov" To: "Commit Messages and Patches for LLVM" Sent: Thursday, November 05, 2009 4:14 PM Subject: [llvm-commits] [PATCH] LTO code generator options Hello everyone, Please find the patch attached. This patch continues the #85419 - Fix to pass options from Gold plugin to LTO codegen. It lets user to specify the target triple, cpu and specific platform attribute (features) for LTO code generator. The following options has been added (names match the llc option names): -mtriple - to set the target triple; -mcpu - to set the target cpu; -mattr - to set additional platform-specific features; If speciffied, these options override all implicit settting. I have also added the -preserve option to keep all intermediate files in place for debug and troubleshooting purposes and did a little code cleaning around my changes to comply with the LLVM coding style policy. Best regards, Viktor From clattner at apple.com Tue Nov 10 13:26:39 2009 From: clattner at apple.com (Chris Lattner) Date: Tue, 10 Nov 2009 11:26:39 -0800 Subject: [llvm-commits] [llvm] r86694 - /llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp In-Reply-To: <200911101821.nAAILbbK027850@zion.cs.uiuc.edu> References: <200911101821.nAAILbbK027850@zion.cs.uiuc.edu> Message-ID: <5841EAC1-CD97-4512-BF44-59AB534401B5@apple.com> On Nov 10, 2009, at 10:21 AM, Duncan Sands wrote: > Author: baldrick > Date: Tue Nov 10 12:21:37 2009 > New Revision: 86694 > > URL: http://llvm.org/viewvc/llvm-project?rev=86694&view=rev > Log: > Fix obvious typo. Can we get a 'break' after it too? :) -Chris > > Modified: > llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp > > Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=86694&r1=86693&r2=86694&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp > (original) > +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Tue > Nov 10 12:21:37 2009 > @@ -142,7 +142,7 @@ > case Intrinsic::init_trampoline: > return -1u; > case Intrinsic::lifetime_end: > - Len = II->getOperand(0); > + Len = II->getOperand(1); > } > } > if (ConstantInt *LenCI = dyn_cast(Len)) > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Tue Nov 10 13:36:40 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 10 Nov 2009 19:36:40 -0000 Subject: [llvm-commits] [llvm] r86705 - /llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Message-ID: <200911101936.nAAJaedH030734@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 10 13:36:40 2009 New Revision: 86705 URL: http://llvm.org/viewvc/llvm-project?rev=86705&view=rev Log: Add defensive break. Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=86705&r1=86704&r2=86705&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Tue Nov 10 13:36:40 2009 @@ -143,6 +143,7 @@ return -1u; case Intrinsic::lifetime_end: Len = II->getOperand(1); + break; } } if (ConstantInt *LenCI = dyn_cast(Len)) From baldrick at free.fr Tue Nov 10 13:37:08 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 10 Nov 2009 20:37:08 +0100 Subject: [llvm-commits] [llvm] r86694 - /llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp In-Reply-To: <5841EAC1-CD97-4512-BF44-59AB534401B5@apple.com> References: <200911101821.nAAILbbK027850@zion.cs.uiuc.edu> <5841EAC1-CD97-4512-BF44-59AB534401B5@apple.com> Message-ID: <4AF9C0E4.2010101@free.fr> > Can we get a 'break' after it too? :) Done in revision 86705. Ciao, Duncan. From evan.cheng at apple.com Tue Nov 10 13:44:56 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 10 Nov 2009 19:44:56 -0000 Subject: [llvm-commits] [llvm] r86706 - /llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Message-ID: <200911101944.nAAJivRW031081@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 10 13:44:56 2009 New Revision: 86706 URL: http://llvm.org/viewvc/llvm-project?rev=86706&view=rev Log: Add a comment. Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=86706&r1=86705&r2=86706&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Tue Nov 10 13:44:56 2009 @@ -418,6 +418,8 @@ // Misc. // +// APSR is the application level alias of CPSR. This FPSCR N, Z, C, V flags +// to APSR. let Defs = [CPSR], Uses = [FPSCR] in def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "vmrs", "\tAPSR_nzcv, FPSCR", From evan.cheng at apple.com Tue Nov 10 13:48:13 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 10 Nov 2009 19:48:13 -0000 Subject: [llvm-commits] [llvm] r86707 - /llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Message-ID: <200911101948.nAAJmDLK031197@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 10 13:48:13 2009 New Revision: 86707 URL: http://llvm.org/viewvc/llvm-project?rev=86707&view=rev Log: Change Thumb1 address mode printing, instead of [r0, #2 * 4] Now [r0, #8] This makes Thumb2 assembly more uniform and frankly the scale doesn't add much. Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=86707&r1=86706&r2=86707&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Tue Nov 10 13:48:13 2009 @@ -715,11 +715,8 @@ O << "[" << getRegisterName(MO1.getReg()); if (MO3.getReg()) O << ", " << getRegisterName(MO3.getReg()); - else if (unsigned ImmOffs = MO2.getImm()) { - O << ", #" << ImmOffs; - if (Scale > 1) - O << " * " << Scale; - } + else if (unsigned ImmOffs = MO2.getImm()) + O << ", #" << ImmOffs * Scale; O << "]"; } From vhernandez at apple.com Tue Nov 10 13:53:28 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Tue, 10 Nov 2009 19:53:28 -0000 Subject: [llvm-commits] [llvm] r86712 - /llvm/trunk/lib/VMCore/Instructions.cpp Message-ID: <200911101953.nAAJrS1R031441@zion.cs.uiuc.edu> Author: hernande Date: Tue Nov 10 13:53:28 2009 New Revision: 86712 URL: http://llvm.org/viewvc/llvm-project?rev=86712&view=rev Log: make this handle redefinition of malloc function with different prototype correctly Modified: llvm/trunk/lib/VMCore/Instructions.cpp Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=86712&r1=86711&r2=86712&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Tue Nov 10 13:53:28 2009 @@ -494,22 +494,21 @@ BasicBlock* BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd; Module* M = BB->getParent()->getParent(); const Type *BPTy = Type::getInt8PtrTy(BB->getContext()); - if (!MallocF) + Value *MallocFunc = MallocF; + if (!MallocFunc) // prototype malloc as "void *malloc(size_t)" - MallocF = cast(M->getOrInsertFunction("malloc", BPTy, - IntPtrTy, NULL)); - if (!MallocF->doesNotAlias(0)) MallocF->setDoesNotAlias(0); + MallocFunc = M->getOrInsertFunction("malloc", BPTy, IntPtrTy, NULL); const PointerType *AllocPtrType = PointerType::getUnqual(AllocTy); CallInst *MCall = NULL; Instruction *Result = NULL; if (InsertBefore) { - MCall = CallInst::Create(MallocF, AllocSize, "malloccall", InsertBefore); + MCall = CallInst::Create(MallocFunc, AllocSize, "malloccall", InsertBefore); Result = MCall; if (Result->getType() != AllocPtrType) // Create a cast instruction to convert to the right type... Result = new BitCastInst(MCall, AllocPtrType, Name, InsertBefore); } else { - MCall = CallInst::Create(MallocF, AllocSize, "malloccall"); + MCall = CallInst::Create(MallocFunc, AllocSize, "malloccall"); Result = MCall; if (Result->getType() != AllocPtrType) { InsertAtEnd->getInstList().push_back(MCall); @@ -518,7 +517,10 @@ } } MCall->setTailCall(); - MCall->setCallingConv(MallocF->getCallingConv()); + if (Function *F = dyn_cast(MallocFunc)) { + MCall->setCallingConv(F->getCallingConv()); + if (!F->doesNotAlias(0)) F->setDoesNotAlias(0); + } assert(MCall->getType() != Type::getVoidTy(BB->getContext()) && "Malloc has void return type"); From vhernandez at apple.com Tue Nov 10 13:54:56 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Tue, 10 Nov 2009 11:54:56 -0800 Subject: [llvm-commits] [llvm] r86525 - /llvm/trunk/lib/VMCore/Instructions.cpp In-Reply-To: <200911090712.nA97C1pV013033@zion.cs.uiuc.edu> References: <200911090712.nA97C1pV013033@zion.cs.uiuc.edu> Message-ID: <745D848F-B85D-4F45-B265-EABAD791A9AC@apple.com> I just realized that this patch only fixed this for CreateFree(), but it also needs to be fixed in CreateMalloc(). Fixed CreateMalloc() in r86712. Victor On Nov 8, 2009, at 11:12 PM, Chris Lattner wrote: > Author: lattner > Date: Mon Nov 9 01:12:01 2009 > New Revision: 86525 > > URL: http://llvm.org/viewvc/llvm-project?rev=86525&view=rev > Log: > make this handle redefinition of malloc with different prototype > correctly. > > Modified: > llvm/trunk/lib/VMCore/Instructions.cpp > > Modified: llvm/trunk/lib/VMCore/Instructions.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=86525&r1=86524&r2=86525&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/VMCore/Instructions.cpp (original) > +++ llvm/trunk/lib/VMCore/Instructions.cpp Mon Nov 9 01:12:01 2009 > @@ -568,8 +568,7 @@ > const Type *VoidTy = Type::getVoidTy(M->getContext()); > const Type *IntPtrTy = Type::getInt8PtrTy(M->getContext()); > // prototype free as "void free(void*)" > - Function *FreeFunc = cast(M->getOrInsertFunction > ("free", VoidTy, > - > IntPtrTy, NULL)); > + Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, > IntPtrTy, NULL); > CallInst* Result = NULL; > Value *PtrCast = Source; > if (InsertBefore) { > @@ -582,7 +581,8 @@ > Result = CallInst::Create(FreeFunc, PtrCast, ""); > } > Result->setTailCall(); > - Result->setCallingConv(FreeFunc->getCallingConv()); > + if (Function *F = dyn_cast(FreeFunc)) > + Result->setCallingConv(F->getCallingConv()); > > return Result; > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gohman at apple.com Tue Nov 10 15:02:18 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 10 Nov 2009 21:02:18 -0000 Subject: [llvm-commits] [llvm] r86714 - /llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll Message-ID: <200911102102.nAAL2IGK001303@zion.cs.uiuc.edu> Author: djg Date: Tue Nov 10 15:02:18 2009 New Revision: 86714 URL: http://llvm.org/viewvc/llvm-project?rev=86714&view=rev Log: Optimize test more. Modified: llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll Modified: llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll?rev=86714&r1=86713&r2=86714&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll (original) +++ llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll Tue Nov 10 15:02:18 2009 @@ -1,4 +1,4 @@ -; RUN: opt < %s -simplifycfg -S +; RUN: opt < %s -simplifycfg -disable-output ; PR3016 ; Dead use caused invariant violation. From vkutuzov at accesssoftek.com Tue Nov 10 15:10:55 2009 From: vkutuzov at accesssoftek.com (Viktor Kutuzov) Date: Tue, 10 Nov 2009 13:10:55 -0800 Subject: [llvm-commits] [PATCH] LTO code generator options: --verbose References: <6AE1604EE3EC5F4296C096518C6B77EEF99C4FAA@mail.accesssoftek.com> Message-ID: <7383326612F04B4DA85C26A2C9A4E6D4@andreic6e7fe55> Hello everyone, This patch adds --verbose LTO code generator option . It also contains some cosmetic changes in the LTOCodeGenerator.cpp file to follow the LLVM coding standards. Is it Ok to submit? Best regards, Viktor -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-lto-codegen_verbose.diff Type: application/octet-stream Size: 10079 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091110/20fd8f66/attachment.obj From evan.cheng at apple.com Tue Nov 10 15:14:06 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 10 Nov 2009 21:14:06 -0000 Subject: [llvm-commits] [llvm] r86715 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/count-to-zero.ll Message-ID: <200911102114.nAALE6ZP001781@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 10 15:14:05 2009 New Revision: 86715 URL: http://llvm.org/viewvc/llvm-project?rev=86715&view=rev Log: Generalize lsr code that optimize loop to count down towards zero. Added: llvm/trunk/test/Transforms/LoopStrengthReduce/count-to-zero.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=86715&r1=86714&r2=86715&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue Nov 10 15:14:05 2009 @@ -51,6 +51,7 @@ STATISTIC(NumShadow, "Number of Shadow IVs optimized"); STATISTIC(NumImmSunk, "Number of common expr immediates sunk into uses"); STATISTIC(NumLoopCond, "Number of loop terminating conds optimized"); +STATISTIC(NumCountZero, "Number of count iv optimized to count toward zero"); static cl::opt EnableFullLSRMode("enable-full-lsr", cl::init(false), @@ -136,7 +137,8 @@ const SCEV *const * &CondStride); void OptimizeIndvars(Loop *L); - void OptimizeLoopCountIV(Loop *L); + void OptimizeLoopCountIV(const SCEV *Stride, + IVUsersOfOneStride &Uses, Loop *L); void OptimizeLoopTermCond(Loop *L); /// OptimizeShadowIV - If IV is used in a int-to-float cast @@ -1519,8 +1521,8 @@ // have the full access expression to rewrite the use. std::vector UsersToProcess; const SCEV *CommonExprs = CollectIVUsers(Stride, Uses, L, AllUsesAreAddresses, - AllUsesAreOutsideLoop, - UsersToProcess); + AllUsesAreOutsideLoop, + UsersToProcess); // Sort the UsersToProcess array so that users with common bases are // next to each other. @@ -1593,8 +1595,8 @@ Type::getInt32Ty(Preheader->getContext())), 0); - /// Choose a strength-reduction strategy and prepare for it by creating - /// the necessary PHIs and adjusting the bookkeeping. + // Choose a strength-reduction strategy and prepare for it by creating + // the necessary PHIs and adjusting the bookkeeping. if (ShouldUseFullStrengthReductionMode(UsersToProcess, L, AllUsesAreAddresses, Stride)) { PrepareToStrengthReduceFully(UsersToProcess, Stride, CommonExprs, L, @@ -2418,107 +2420,142 @@ ++NumLoopCond; } +/// isUsedByExitBranch - Return true if icmp is used by a loop terminating +/// conditional branch or it's and / or with other conditions before being used +/// as the condition. +static bool isUsedByExitBranch(ICmpInst *Cond, Loop *L) { + BasicBlock *CondBB = Cond->getParent(); + if (!L->isLoopExiting(CondBB)) + return false; + BranchInst *TermBr = dyn_cast(CondBB->getTerminator()); + if (!TermBr->isConditional()) + return false; + + Value *User = *Cond->use_begin(); + Instruction *UserInst = dyn_cast(User); + while (UserInst && + (UserInst->getOpcode() == Instruction::And || + UserInst->getOpcode() == Instruction::Or)) { + if (!UserInst->hasOneUse() || UserInst->getParent() != CondBB) + return false; + User = *User->use_begin(); + UserInst = dyn_cast(User); + } + return User == TermBr; +} + /// OptimizeLoopCountIV - If, after all sharing of IVs, the IV used for deciding /// when to exit the loop is used only for that purpose, try to rearrange things -/// so it counts down to a test against zero. -void LoopStrengthReduce::OptimizeLoopCountIV(Loop *L) { - - // If the number of times the loop is executed isn't computable, give up. - const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L); - if (isa(BackedgeTakenCount)) +/// so it counts down to a test against zero which tends to be cheaper. +void LoopStrengthReduce::OptimizeLoopCountIV(const SCEV *Stride, + IVUsersOfOneStride &Uses, + Loop *L) { + if (Uses.Users.size() != 1) return; - // Get the terminating condition for the loop if possible (this isn't - // necessarily in the latch, or a block that's a predecessor of the header). - if (!L->getExitBlock()) - return; // More than one loop exit blocks. - - // Okay, there is one exit block. Try to find the condition that causes the - // loop to be exited. - BasicBlock *ExitingBlock = L->getExitingBlock(); - if (!ExitingBlock) - return; // More than one block exiting! - - // Okay, we've computed the exiting block. See what condition causes us to - // exit. - // - // FIXME: we should be able to handle switch instructions (with a single exit) - BranchInst *TermBr = dyn_cast(ExitingBlock->getTerminator()); - if (TermBr == 0) return; - assert(TermBr->isConditional() && "If unconditional, it can't be in loop!"); - if (!isa(TermBr->getCondition())) + // If the only use is an icmp of an loop exiting conditional branch, then + // attempts the optimization. + BasedUser User = BasedUser(*Uses.Users.begin(), SE); + Instruction *Inst = User.Inst; + if (!L->contains(Inst->getParent())) return; - ICmpInst *Cond = cast(TermBr->getCondition()); - // Handle only tests for equality for the moment, and only stride 1. - if (Cond->getPredicate() != CmpInst::ICMP_EQ) + ICmpInst *Cond = dyn_cast(Inst); + if (!Cond) return; - const SCEV *IV = SE->getSCEV(Cond->getOperand(0)); + // Handle only tests for equality for the moment. + if (Cond->getPredicate() != CmpInst::ICMP_EQ || !Cond->hasOneUse()) + return; + if (!isUsedByExitBranch(Cond, L)) + return; + + Value *CondOp0 = Cond->getOperand(0); + const SCEV *IV = SE->getSCEV(CondOp0); const SCEVAddRecExpr *AR = dyn_cast(IV); - const SCEV *One = SE->getIntegerSCEV(1, BackedgeTakenCount->getType()); - if (!AR || !AR->isAffine() || AR->getStepRecurrence(*SE) != One) + if (!AR || !AR->isAffine()) + return; + + const SCEVConstant *SC = dyn_cast(AR->getStepRecurrence(*SE)); + if (!SC || SC->getValue()->getSExtValue() < 0) + // If it's already counting down, don't do anything. + return; + + // If the RHS of the comparison is not an loop invariant, the rewrite + // cannot be done. Also bail out if it's already comparing against a zero. + Value *RHS = Cond->getOperand(1); + if (!L->isLoopInvariant(RHS) || + (isa(RHS) && cast(RHS)->isZero())) return; - // If the RHS of the comparison is defined inside the loop, the rewrite - // cannot be done. - if (Instruction *CR = dyn_cast(Cond->getOperand(1))) - if (L->contains(CR->getParent())) - return; // Make sure the IV is only used for counting. Value may be preinc or // postinc; 2 uses in either case. - if (!Cond->getOperand(0)->hasNUses(2)) + if (!CondOp0->hasNUses(2)) return; - PHINode *phi = dyn_cast(Cond->getOperand(0)); - Instruction *incr; - if (phi && phi->getParent()==L->getHeader()) { - // value tested is preinc. Find the increment. - // A CmpInst is not a BinaryOperator; we depend on this. - Instruction::use_iterator UI = phi->use_begin(); - incr = dyn_cast(UI); - if (!incr) - incr = dyn_cast(++UI); - // 1 use for postinc value, the phi. Unnecessarily conservative? - if (!incr || !incr->hasOneUse() || incr->getOpcode()!=Instruction::Add) - return; - } else { - // Value tested is postinc. Find the phi node. - incr = dyn_cast(Cond->getOperand(0)); - if (!incr || incr->getOpcode()!=Instruction::Add) + PHINode *PHIExpr; + Instruction *Incr; + if (User.isUseOfPostIncrementedValue) { + // Value tested is postinc. Find the phi node. + Incr = dyn_cast(CondOp0); + if (!Incr || Incr->getOpcode() != Instruction::Add) return; - Instruction::use_iterator UI = Cond->getOperand(0)->use_begin(); - phi = dyn_cast(UI); - if (!phi) - phi = dyn_cast(++UI); + Instruction::use_iterator UI = CondOp0->use_begin(); + PHIExpr = dyn_cast(UI); + if (!PHIExpr) + PHIExpr = dyn_cast(++UI); // 1 use for preinc value, the increment. - if (!phi || phi->getParent()!=L->getHeader() || !phi->hasOneUse()) + if (!PHIExpr || !PHIExpr->hasOneUse()) + return; + } else { + assert(isa(CondOp0) && + "Unexpected loop exiting counting instruction sequence!"); + PHIExpr = cast(CondOp0); + // Value tested is preinc. Find the increment. + // A CmpInst is not a BinaryOperator; we depend on this. + Instruction::use_iterator UI = PHIExpr->use_begin(); + Incr = dyn_cast(UI); + if (!Incr) + Incr = dyn_cast(++UI); + // One use for postinc value, the phi. Unnecessarily conservative? + if (!Incr || !Incr->hasOneUse() || Incr->getOpcode() != Instruction::Add) return; } // Replace the increment with a decrement. - BinaryOperator *decr = - BinaryOperator::Create(Instruction::Sub, incr->getOperand(0), - incr->getOperand(1), "tmp", incr); - incr->replaceAllUsesWith(decr); - incr->eraseFromParent(); + DEBUG(errs() << " Examining "); + if (User.isUseOfPostIncrementedValue) + DEBUG(errs() << "postinc"); + else + DEBUG(errs() << "preinc"); + DEBUG(errs() << " use "); + DEBUG(WriteAsOperand(errs(), CondOp0, /*PrintType=*/false)); + DEBUG(errs() << " in Inst: " << *Inst << '\n'); + BinaryOperator *Decr = BinaryOperator::Create(Instruction::Sub, + Incr->getOperand(0), Incr->getOperand(1), "tmp", Incr); + Incr->replaceAllUsesWith(Decr); + Incr->eraseFromParent(); // Substitute endval-startval for the original startval, and 0 for the // original endval. Since we're only testing for equality this is OK even // if the computation wraps around. BasicBlock *Preheader = L->getLoopPreheader(); Instruction *PreInsertPt = Preheader->getTerminator(); - int inBlock = L->contains(phi->getIncomingBlock(0)) ? 1 : 0; - Value *startVal = phi->getIncomingValue(inBlock); - Value *endVal = Cond->getOperand(1); - // FIXME check for case where both are constant + unsigned InBlock = L->contains(PHIExpr->getIncomingBlock(0)) ? 1 : 0; + Value *StartVal = PHIExpr->getIncomingValue(InBlock); + Value *EndVal = Cond->getOperand(1); + DEBUG(errs() << " Optimize loop counting iv to count down [" + << *EndVal << " .. " << *StartVal << "]\n"); + + // FIXME: check for case where both are constant. Constant* Zero = ConstantInt::get(Cond->getOperand(1)->getType(), 0); - BinaryOperator *NewStartVal = - BinaryOperator::Create(Instruction::Sub, endVal, startVal, - "tmp", PreInsertPt); - phi->setIncomingValue(inBlock, NewStartVal); + BinaryOperator *NewStartVal = BinaryOperator::Create(Instruction::Sub, + EndVal, StartVal, "tmp", PreInsertPt); + PHIExpr->setIncomingValue(InBlock, NewStartVal); Cond->setOperand(1, Zero); + DEBUG(errs() << " New icmp: " << *Cond << "\n"); Changed = true; + ++NumCountZero; } bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager &LPM) { @@ -2581,11 +2618,20 @@ continue; StrengthReduceStridedIVUsers(SI->first, *SI->second, L); } - } - // After all sharing is done, see if we can adjust the loop to test against - // zero instead of counting up to a maximum. This is usually faster. - OptimizeLoopCountIV(L); + // After all sharing is done, see if we can adjust the loop to test against + // zero instead of counting up to a maximum. This is usually faster. + for (unsigned Stride = 0, e = IU->StrideOrder.size(); + Stride != e; ++Stride) { + std::map::iterator SI = + IU->IVUsesByStride.find(IU->StrideOrder[Stride]); + assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!"); + // FIXME: Generalize to non-affine IV's. + if (!SI->first->isLoopInvariant(L)) + continue; + OptimizeLoopCountIV(SI->first, *SI->second, L); + } + } // We're done analyzing this loop; release all the state we built up for it. IVsByStride.clear(); Added: llvm/trunk/test/Transforms/LoopStrengthReduce/count-to-zero.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopStrengthReduce/count-to-zero.ll?rev=86715&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopStrengthReduce/count-to-zero.ll (added) +++ llvm/trunk/test/Transforms/LoopStrengthReduce/count-to-zero.ll Tue Nov 10 15:14:05 2009 @@ -0,0 +1,42 @@ +; RUN: opt < %s -loop-reduce -S | FileCheck %s +; rdar://7382068 + +define void @t(i32 %c) nounwind optsize { +entry: + br label %bb6 + +bb1: ; preds = %bb6 + %tmp = icmp eq i32 %c_addr.1, 20 ; [#uses=1] + br i1 %tmp, label %bb2, label %bb3 + +bb2: ; preds = %bb1 + %tmp1 = tail call i32 @f20(i32 %c_addr.1) nounwind ; [#uses=1] + br label %bb7 + +bb3: ; preds = %bb1 + %tmp2 = icmp slt i32 %c_addr.1, 10 ; [#uses=1] + %tmp3 = add nsw i32 %c_addr.1, 1 ; [#uses=1] + %tmp4 = add i32 %c_addr.1, -1 ; [#uses=1] + %c_addr.1.be = select i1 %tmp2, i32 %tmp3, i32 %tmp4 ; [#uses=1] + %indvar.next = add i32 %indvar, 1 ; [#uses=1] +; CHECK: sub i32 %lsr.iv, 1 + br label %bb6 + +bb6: ; preds = %bb3, %entry + %indvar = phi i32 [ %indvar.next, %bb3 ], [ 0, %entry ] ; [#uses=2] + %c_addr.1 = phi i32 [ %c_addr.1.be, %bb3 ], [ %c, %entry ] ; [#uses=7] + %tmp5 = icmp eq i32 %indvar, 9999 ; [#uses=1] +; CHECK: icmp eq i32 %lsr.iv, 0 + %tmp6 = icmp eq i32 %c_addr.1, 100 ; [#uses=1] + %or.cond = or i1 %tmp5, %tmp6 ; [#uses=1] + br i1 %or.cond, label %bb7, label %bb1 + +bb7: ; preds = %bb6, %bb2 + %c_addr.0 = phi i32 [ %tmp1, %bb2 ], [ %c_addr.1, %bb6 ] ; [#uses=1] + tail call void @bar(i32 %c_addr.0) nounwind + ret void +} + +declare i32 @f20(i32) + +declare void @bar(i32) From echristo at apple.com Tue Nov 10 15:15:40 2009 From: echristo at apple.com (Eric Christopher) Date: Tue, 10 Nov 2009 13:15:40 -0800 Subject: [llvm-commits] [PATCH] LTO code generator options: --verbose In-Reply-To: <7383326612F04B4DA85C26A2C9A4E6D4@andreic6e7fe55> References: <6AE1604EE3EC5F4296C096518C6B77EEF99C4FAA@mail.accesssoftek.com> <7383326612F04B4DA85C26A2C9A4E6D4@andreic6e7fe55> Message-ID: <4C3AAB5F-812D-4811-A1EE-DEF04E0F29EE@apple.com> On Nov 10, 2009, at 1:10 PM, Viktor Kutuzov wrote: > It'd be easier to look at if there were less cosmetic changes in the patch. That said, what do you expect this will add? -eric From sabre at nondot.org Tue Nov 10 15:40:01 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 21:40:01 -0000 Subject: [llvm-commits] [llvm] r86722 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/basic.ll Message-ID: <200911102140.nAALe21i002831@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 15:40:01 2009 New Revision: 86722 URL: http://llvm.org/viewvc/llvm-project?rev=86722&view=rev Log: Make jump threading eliminate blocks that just contain phi nodes, debug intrinsics, and an unconditional branch when possible. This reuses the TryToSimplifyUncondBranchFromEmptyBlock function split out of simplifycfg. Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp llvm/trunk/test/Transforms/JumpThreading/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86722&r1=86721&r2=86722&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Tue Nov 10 15:40:01 2009 @@ -115,6 +115,7 @@ bool Changed = false; for (Function::iterator I = F.begin(), E = F.end(); I != E;) { BasicBlock *BB = I; + // Thread all of the branches we can over this block. while (ProcessBlock(BB)) Changed = true; @@ -129,6 +130,26 @@ LoopHeaders.erase(BB); DeleteDeadBlock(BB); Changed = true; + } else if (BranchInst *BI = dyn_cast(BB->getTerminator())) { + // Can't thread an unconditional jump, but if the block is "almost + // empty", we can replace uses of it with uses of the successor and make + // this dead. + if (BI->isUnconditional() && + BB != &BB->getParent()->getEntryBlock()) { + BasicBlock::iterator BBI = BB->getFirstNonPHI(); + // Ignore dbg intrinsics. + while (isa(BBI)) + ++BBI; + // If the terminator is the only non-phi instruction, try to nuke it. + if (BBI->isTerminator()) { + bool Erased = LoopHeaders.erase(BB); + + if (TryToSimplifyUncondBranchFromEmptyBlock(BB)) + Changed = true; + else if (Erased) + LoopHeaders.insert(BB); + } + } } } AnotherIteration = Changed; Modified: llvm/trunk/test/Transforms/JumpThreading/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/basic.ll?rev=86722&r1=86721&r2=86722&view=diff ============================================================================== --- llvm/trunk/test/Transforms/JumpThreading/basic.ll (original) +++ llvm/trunk/test/Transforms/JumpThreading/basic.ll Tue Nov 10 15:40:01 2009 @@ -211,19 +211,29 @@ T0: %A = call i1 @test8a() br i1 %A, label %T1, label %F1 + +; CHECK: T0: +; CHECK-NEXT: call +; CHECK-NEXT: br i1 %A, label %T1, label %Y + T1: %B = call i1 @test8a() br i1 %B, label %T2, label %F1 + +; CHECK: T1: +; CHECK-NEXT: call +; CHECK-NEXT: br i1 %B, label %T2, label %Y T2: %C = call i1 @test8a() br i1 %cond, label %T3, label %F1 + +; CHECK: T2: +; CHECK-NEXT: call +; CHECK-NEXT: br i1 %cond, label %T3, label %Y T3: ret i32 0 F1: -; TODO: F1 uncond branch block should be removed, T2 should jump directly to Y. -; CHECK: F1: -; CHECK-NEXT br label %Y %D = phi i32 [0, %T0], [0, %T1], [1, %T2] %E = icmp eq i32 %D, 1 %F = and i1 %E, %cond From sabre at nondot.org Tue Nov 10 15:45:09 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 21:45:09 -0000 Subject: [llvm-commits] [llvm] r86723 - /llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200911102145.nAALj9aC002980@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 15:45:09 2009 New Revision: 86723 URL: http://llvm.org/viewvc/llvm-project?rev=86723&view=rev Log: improve comment. Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86723&r1=86722&r2=86723&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Tue Nov 10 15:45:09 2009 @@ -142,11 +142,14 @@ ++BBI; // If the terminator is the only non-phi instruction, try to nuke it. if (BBI->isTerminator()) { - bool Erased = LoopHeaders.erase(BB); + // Since TryToSimplifyUncondBranchFromEmptyBlock may delete the + // block, we have to make sure it isn't in the LoopHeaders set. We + // reinsert afterward in the rare case when the block isn't deleted. + bool ErasedFromLoopHeaders = LoopHeaders.erase(BB); if (TryToSimplifyUncondBranchFromEmptyBlock(BB)) Changed = true; - else if (Erased) + else if (ErasedFromLoopHeaders) LoopHeaders.insert(BB); } } From stoklund at 2pi.dk Tue Nov 10 16:00:56 2009 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 10 Nov 2009 22:00:56 -0000 Subject: [llvm-commits] [llvm] r86724 - in /llvm/trunk/lib/CodeGen: PHIElimination.cpp PHIElimination.h Message-ID: <200911102200.nAAM0uSI003534@zion.cs.uiuc.edu> Author: stoklund Date: Tue Nov 10 16:00:56 2009 New Revision: 86724 URL: http://llvm.org/viewvc/llvm-project?rev=86724&view=rev Log: Refactoring: Extract method PHIElimination::isLiveOut(). Clean up some whitespace. No functional changes. Modified: llvm/trunk/lib/CodeGen/PHIElimination.cpp llvm/trunk/lib/CodeGen/PHIElimination.h Modified: llvm/trunk/lib/CodeGen/PHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIElimination.cpp?rev=86724&r1=86723&r2=86724&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/PHIElimination.cpp Tue Nov 10 16:00:56 2009 @@ -155,7 +155,7 @@ /// under the assuption that it needs to be lowered in a way that supports /// atomic execution of PHIs. This lowering method is always correct all of the /// time. -/// +/// void llvm::PHIElimination::LowerAtomicPHINode( MachineBasicBlock &MBB, MachineBasicBlock::iterator AfterPHIsIt) { @@ -186,7 +186,7 @@ } // Record PHI def. - assert(!hasPHIDef(DestReg) && "Vreg has multiple phi-defs?"); + assert(!hasPHIDef(DestReg) && "Vreg has multiple phi-defs?"); PHIDefs[DestReg] = &MBB; // Update live variable information if there is any. @@ -250,7 +250,7 @@ // basic block. if (!MBBsInsertedInto.insert(&opBlock)) continue; // If the copy has already been emitted, we're done. - + // Find a safe location to insert the copy, this may be the first terminator // in the block (or end()). MachineBasicBlock::iterator InsertPos = FindCopyInsertPoint(opBlock, SrcReg); @@ -260,82 +260,24 @@ // Now update live variable information if we have it. Otherwise we're done if (!LV) continue; - + // We want to be able to insert a kill of the register if this PHI (aka, the // copy we just inserted) is the last use of the source value. Live // variable analysis conservatively handles this by saying that the value is // live until the end of the block the PHI entry lives in. If the value // really is dead at the PHI copy, there will be no successor blocks which // have the value live-in. - // - // Check to see if the copy is the last use, and if so, update the live - // variables information so that it knows the copy source instruction kills - // the incoming value. - LiveVariables::VarInfo &InRegVI = LV->getVarInfo(SrcReg); - // Loop over all of the successors of the basic block, checking to see if - // the value is either live in the block, or if it is killed in the block. // Also check to see if this register is in use by another PHI node which // has not yet been eliminated. If so, it will be killed at an appropriate // point later. // Is it used by any PHI instructions in this block? - bool ValueIsLive = VRegPHIUseCount[BBVRegPair(&opBlock, SrcReg)] != 0; - - std::vector OpSuccBlocks; - - // Otherwise, scan successors, including the BB the PHI node lives in. - for (MachineBasicBlock::succ_iterator SI = opBlock.succ_begin(), - E = opBlock.succ_end(); SI != E && !ValueIsLive; ++SI) { - MachineBasicBlock *SuccMBB = *SI; - - // Is it alive in this successor? - unsigned SuccIdx = SuccMBB->getNumber(); - if (InRegVI.AliveBlocks.test(SuccIdx)) { - ValueIsLive = true; - break; - } - - OpSuccBlocks.push_back(SuccMBB); - } - - // Check to see if this value is live because there is a use in a successor - // that kills it. - if (!ValueIsLive) { - switch (OpSuccBlocks.size()) { - case 1: { - MachineBasicBlock *MBB = OpSuccBlocks[0]; - for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) - if (InRegVI.Kills[i]->getParent() == MBB) { - ValueIsLive = true; - break; - } - break; - } - case 2: { - MachineBasicBlock *MBB1 = OpSuccBlocks[0], *MBB2 = OpSuccBlocks[1]; - for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) - if (InRegVI.Kills[i]->getParent() == MBB1 || - InRegVI.Kills[i]->getParent() == MBB2) { - ValueIsLive = true; - break; - } - break; - } - default: - std::sort(OpSuccBlocks.begin(), OpSuccBlocks.end()); - for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) - if (std::binary_search(OpSuccBlocks.begin(), OpSuccBlocks.end(), - InRegVI.Kills[i]->getParent())) { - ValueIsLive = true; - break; - } - } - } + bool ValueIsUsed = VRegPHIUseCount[BBVRegPair(&opBlock, SrcReg)] != 0; // Okay, if we now know that the value is not live out of the block, we can // add a kill marker in this block saying that it kills the incoming value! - if (!ValueIsLive) { + if (!ValueIsUsed && !isLiveOut(SrcReg, opBlock, *LV)) { // In our final twist, we have to decide which instruction kills the // register. In most cases this is the copy, however, the first // terminator instruction at the end of the block may also use the value. @@ -346,7 +288,7 @@ if (Term != opBlock.end()) { if (Term->readsRegister(SrcReg)) KillInst = Term; - + // Check that no other terminators use values. #ifndef NDEBUG for (MachineBasicBlock::iterator TI = next(Term); TI != opBlock.end(); @@ -357,16 +299,16 @@ } #endif } - + // Finally, mark it killed. LV->addVirtualRegisterKilled(SrcReg, KillInst); // This vreg no longer lives all of the way through opBlock. unsigned opBlockNum = opBlock.getNumber(); - InRegVI.AliveBlocks.reset(opBlockNum); + LV->getVarInfo(SrcReg).AliveBlocks.reset(opBlockNum); } } - + // Really delete the PHI instruction now! MF.DeleteMachineInstr(MPhi); ++NumAtomic; @@ -386,3 +328,51 @@ ++VRegPHIUseCount[BBVRegPair(BBI->getOperand(i + 1).getMBB(), BBI->getOperand(i).getReg())]; } + +bool llvm::PHIElimination::isLiveOut(unsigned Reg, const MachineBasicBlock &MBB, + LiveVariables &LV) { + LiveVariables::VarInfo &InRegVI = LV.getVarInfo(Reg); + + // Loop over all of the successors of the basic block, checking to see if + // the value is either live in the block, or if it is killed in the block. + std::vector OpSuccBlocks; + + // Otherwise, scan successors, including the BB the PHI node lives in. + for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(), + E = MBB.succ_end(); SI != E; ++SI) { + MachineBasicBlock *SuccMBB = *SI; + + // Is it alive in this successor? + unsigned SuccIdx = SuccMBB->getNumber(); + if (InRegVI.AliveBlocks.test(SuccIdx)) + return true; + OpSuccBlocks.push_back(SuccMBB); + } + + // Check to see if this value is live because there is a use in a successor + // that kills it. + switch (OpSuccBlocks.size()) { + case 1: { + MachineBasicBlock *SuccMBB = OpSuccBlocks[0]; + for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) + if (InRegVI.Kills[i]->getParent() == SuccMBB) + return true; + break; + } + case 2: { + MachineBasicBlock *SuccMBB1 = OpSuccBlocks[0], *SuccMBB2 = OpSuccBlocks[1]; + for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) + if (InRegVI.Kills[i]->getParent() == SuccMBB1 || + InRegVI.Kills[i]->getParent() == SuccMBB2) + return true; + break; + } + default: + std::sort(OpSuccBlocks.begin(), OpSuccBlocks.end()); + for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) + if (std::binary_search(OpSuccBlocks.begin(), OpSuccBlocks.end(), + InRegVI.Kills[i]->getParent())) + return true; + } + return false; +} Modified: llvm/trunk/lib/CodeGen/PHIElimination.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIElimination.h?rev=86724&r1=86723&r2=86724&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PHIElimination.h (original) +++ llvm/trunk/lib/CodeGen/PHIElimination.h Tue Nov 10 16:00:56 2009 @@ -89,6 +89,12 @@ /// void analyzePHINodes(const MachineFunction& Fn); + /// isLiveOut - Determine if Reg is live out from MBB, when not + /// considering PHI nodes. This means that Reg is either killed by + /// a successor block or passed through one. + bool isLiveOut(unsigned Reg, const MachineBasicBlock &MBB, + LiveVariables &LV); + // FindCopyInsertPoint - Find a safe place in MBB to insert a copy from // SrcReg. This needs to be after any def or uses of SrcReg, but before // any subsequent point where control flow might jump out of the basic From stoklund at 2pi.dk Tue Nov 10 16:01:05 2009 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 10 Nov 2009 22:01:05 -0000 Subject: [llvm-commits] [llvm] r86725 - in /llvm/trunk: include/llvm/CodeGen/LiveVariables.h lib/CodeGen/LiveVariables.cpp lib/CodeGen/PHIElimination.cpp lib/CodeGen/PHIElimination.h Message-ID: <200911102201.nAAM15qf003564@zion.cs.uiuc.edu> Author: stoklund Date: Tue Nov 10 16:01:05 2009 New Revision: 86725 URL: http://llvm.org/viewvc/llvm-project?rev=86725&view=rev Log: Teach PHIElimination to split critical edges when -split-phi-edges is enabled. Critical edges leading to a PHI node are split when the PHI source variable is live out from the predecessor block. This help the coalescer eliminate more PHI joins. Modified: llvm/trunk/include/llvm/CodeGen/LiveVariables.h llvm/trunk/lib/CodeGen/LiveVariables.cpp llvm/trunk/lib/CodeGen/PHIElimination.cpp llvm/trunk/lib/CodeGen/PHIElimination.h Modified: llvm/trunk/include/llvm/CodeGen/LiveVariables.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveVariables.h?rev=86725&r1=86724&r2=86725&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveVariables.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveVariables.h Tue Nov 10 16:01:05 2009 @@ -103,7 +103,10 @@ Kills.erase(I); return true; } - + + /// findKill - Find a kill instruction in MBB. Return NULL if none is found. + MachineInstr *findKill(const MachineBasicBlock *MBB) const; + void dump() const; }; @@ -263,6 +266,10 @@ void HandleVirtRegDef(unsigned reg, MachineInstr *MI); void HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB, MachineInstr *MI); + + /// addNewBlock - Add a new basic block A as an empty predecessor of B. All + /// variables that are live into B will be marked as passing live through A. + void addNewBlock(MachineBasicBlock *A, MachineBasicBlock *B); }; } // End llvm namespace Modified: llvm/trunk/lib/CodeGen/LiveVariables.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveVariables.cpp?rev=86725&r1=86724&r2=86725&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveVariables.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveVariables.cpp Tue Nov 10 16:01:05 2009 @@ -50,6 +50,14 @@ MachineFunctionPass::getAnalysisUsage(AU); } +MachineInstr * +LiveVariables::VarInfo::findKill(const MachineBasicBlock *MBB) const { + for (unsigned i = 0, e = Kills.size(); i != e; ++i) + if (Kills[i]->getParent() == MBB) + return Kills[i]; + return NULL; +} + void LiveVariables::VarInfo::dump() const { errs() << " Alive in blocks: "; for (SparseBitVector<>::iterator I = AliveBlocks.begin(), @@ -641,3 +649,35 @@ PHIVarInfo[BBI->getOperand(i + 1).getMBB()->getNumber()] .push_back(BBI->getOperand(i).getReg()); } + +void LiveVariables::addNewBlock(MachineBasicBlock *A, MachineBasicBlock *B) { + unsigned NumA = A->getNumber(); + unsigned NumB = B->getNumber(); + + // Update info for all live variables + for (unsigned i = 0, e = VirtRegInfo.size(); i != e; ++i) { + VarInfo &VI = VirtRegInfo[i]; + + // Anything live through B is also live through A. + if (VI.AliveBlocks.test(NumB)) { + VI.AliveBlocks.set(NumA); + continue; + } + + // If we're not killed in B, we are not live in + if (!VI.findKill(B)) + continue; + + unsigned Reg = i+TargetRegisterInfo::FirstVirtualRegister; + + // Find a def outside B + for (MachineRegisterInfo::def_iterator di = MRI->def_begin(Reg), + de=MRI->def_end(); di != de; ++di) { + if (di->getParent() != B) { + // Reg was defined outside B and killed in B - it must be live in. + VI.AliveBlocks.set(NumA); + break; + } + } + } +} Modified: llvm/trunk/lib/CodeGen/PHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIElimination.cpp?rev=86725&r1=86724&r2=86725&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/PHIElimination.cpp Tue Nov 10 16:01:05 2009 @@ -27,12 +27,20 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" #include #include using namespace llvm; STATISTIC(NumAtomic, "Number of atomic phis lowered"); +STATISTIC(NumSplits, "Number of critical edges split on demand"); + +static cl::opt +SplitEdges("split-phi-edges", + cl::desc("Split critical edges during phi elimination"), + cl::init(false), cl::Hidden); char PHIElimination::ID = 0; static RegisterPass @@ -41,10 +49,14 @@ const PassInfo *const llvm::PHIEliminationID = &X; void llvm::PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesCFG(); AU.addPreserved(); - AU.addPreservedID(MachineLoopInfoID); - AU.addPreservedID(MachineDominatorsID); + if (SplitEdges) { + AU.addRequired(); + } else { + AU.setPreservesCFG(); + AU.addPreservedID(MachineLoopInfoID); + AU.addPreservedID(MachineDominatorsID); + } MachineFunctionPass::getAnalysisUsage(AU); } @@ -84,6 +96,9 @@ if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI) return false; // Quick exit for basic blocks without PHIs. + if (SplitEdges) + SplitPHIEdges(MF, MBB); + // Get an iterator to the first instruction after the last PHI node (this may // also be the end of the basic block). MachineBasicBlock::iterator AfterPHIsIt = SkipPHIsAndLabels(MBB, MBB.begin()); @@ -277,7 +292,8 @@ // Okay, if we now know that the value is not live out of the block, we can // add a kill marker in this block saying that it kills the incoming value! - if (!ValueIsUsed && !isLiveOut(SrcReg, opBlock, *LV)) { + // When SplitEdges is enabled, the value is never live out. + if (!ValueIsUsed && (SplitEdges || !isLiveOut(SrcReg, opBlock, *LV))) { // In our final twist, we have to decide which instruction kills the // register. In most cases this is the copy, however, the first // terminator instruction at the end of the block may also use the value. @@ -329,6 +345,22 @@ BBI->getOperand(i).getReg())]; } +void llvm::PHIElimination::SplitPHIEdges(MachineFunction &MF, + MachineBasicBlock &MBB) { + LiveVariables &LV = getAnalysis(); + for (MachineBasicBlock::const_iterator BBI = MBB.begin(), BBE = MBB.end(); + BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI) { + for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) { + unsigned Reg = BBI->getOperand(i).getReg(); + MachineBasicBlock *PreMBB = BBI->getOperand(i+1).getMBB(); + // We break edges when registers are live out from the predecessor block + // (not considering PHI nodes). + if (isLiveOut(Reg, *PreMBB, LV)) + SplitCriticalEdge(PreMBB, &MBB); + } + } +} + bool llvm::PHIElimination::isLiveOut(unsigned Reg, const MachineBasicBlock &MBB, LiveVariables &LV) { LiveVariables::VarInfo &InRegVI = LV.getVarInfo(Reg); @@ -376,3 +408,43 @@ } return false; } + +MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A, + MachineBasicBlock *B) { + assert(A && B && "Missing MBB end point"); + ++NumSplits; + + MachineFunction *MF = A->getParent(); + MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock(B->getBasicBlock()); + MF->push_back(NMBB); + const unsigned NewNum = NMBB->getNumber(); + DEBUG(errs() << "PHIElimination splitting critical edge:" + " BB#" << A->getNumber() + << " -- BB#" << NewNum + << " -- BB#" << B->getNumber() << '\n'); + + A->ReplaceUsesOfBlockWith(B, NMBB); + NMBB->addSuccessor(B); + + // Insert unconditional "jump B" instruction in NMBB. + SmallVector Cond; + MF->getTarget().getInstrInfo()->InsertBranch(*NMBB, B, NULL, Cond); + + LiveVariables *LV = getAnalysisIfAvailable(); + if (LV) + LV->addNewBlock(NMBB, B); + + // Fix PHI nodes in B so they refer to NMBB instead of A + for (MachineBasicBlock::iterator i = B->begin(), e = B->end(); + i != e && i->getOpcode() == TargetInstrInfo::PHI; ++i) + for (unsigned ni = 1, ne = i->getNumOperands(); ni != ne; ni += 2) + if (i->getOperand(ni+1).getMBB() == A) { + i->getOperand(ni+1).setMBB(NMBB); + // Mark PHI sources as passing live through NMBB + if (LV) + LV->getVarInfo(i->getOperand(ni).getReg()).AliveBlocks.set(NewNum); + } + return NMBB; +} + + Modified: llvm/trunk/lib/CodeGen/PHIElimination.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIElimination.h?rev=86725&r1=86724&r2=86725&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PHIElimination.h (original) +++ llvm/trunk/lib/CodeGen/PHIElimination.h Tue Nov 10 16:01:05 2009 @@ -89,12 +89,21 @@ /// void analyzePHINodes(const MachineFunction& Fn); + /// Split critical edges where necessary for good coalescer performance. + void SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB); + /// isLiveOut - Determine if Reg is live out from MBB, when not /// considering PHI nodes. This means that Reg is either killed by /// a successor block or passed through one. bool isLiveOut(unsigned Reg, const MachineBasicBlock &MBB, LiveVariables &LV); + /// SplitCriticalEdge - Split a critical edge from A to B by + /// inserting a new MBB. Update branches in A and PHI instructions + /// in B. Return the new block. + MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *A, + MachineBasicBlock *B); + // FindCopyInsertPoint - Find a safe place in MBB to insert a copy from // SrcReg. This needs to be after any def or uses of SrcReg, but before // any subsequent point where control flow might jump out of the basic From sabre at nondot.org Tue Nov 10 16:02:09 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 22:02:09 -0000 Subject: [llvm-commits] [llvm] r86726 - in /llvm/trunk: lib/Transforms/Scalar/SCCP.cpp test/Transforms/SCCP/crash.ll Message-ID: <200911102202.nAAM29cT003603@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 16:02:09 2009 New Revision: 86726 URL: http://llvm.org/viewvc/llvm-project?rev=86726&view=rev Log: fix a crash in SCCP handling extractvalue of an array, pointed out and tracked down by Stephan Reiter! Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp llvm/trunk/test/Transforms/SCCP/crash.ll Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=86726&r1=86725&r2=86726&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Tue Nov 10 16:02:09 2009 @@ -795,9 +795,14 @@ return markOverdefined(&EVI); Value *AggVal = EVI.getAggregateOperand(); - unsigned i = *EVI.idx_begin(); - LatticeVal EltVal = getStructValueState(AggVal, i); - mergeInValue(getValueState(&EVI), &EVI, EltVal); + if (isa(AggVal->getType())) { + unsigned i = *EVI.idx_begin(); + LatticeVal EltVal = getStructValueState(AggVal, i); + mergeInValue(getValueState(&EVI), &EVI, EltVal); + } else { + // Otherwise, must be extracting from an array. + return markOverdefined(&EVI); + } } void SCCPSolver::visitInsertValueInst(InsertValueInst &IVI) { Modified: llvm/trunk/test/Transforms/SCCP/crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/crash.ll?rev=86726&r1=86725&r2=86726&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SCCP/crash.ll (original) +++ llvm/trunk/test/Transforms/SCCP/crash.ll Tue Nov 10 16:02:09 2009 @@ -22,3 +22,8 @@ return: ret void } + +define i32 @test2([4 x i32] %A) { + %B = extractvalue [4 x i32] %A, 1 + ret i32 %B +} From dpatel at apple.com Tue Nov 10 16:05:35 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 10 Nov 2009 22:05:35 -0000 Subject: [llvm-commits] [llvm] r86727 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h lib/Analysis/DebugInfo.cpp Message-ID: <200911102205.nAAM5aOF003756@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 10 16:05:35 2009 New Revision: 86727 URL: http://llvm.org/viewvc/llvm-project?rev=86727&view=rev Log: Process InlinedAt location info. Update InsertDeclare to return newly inserted llvm.dbg.declare intrinsic. Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h llvm/trunk/lib/Analysis/DebugInfo.cpp Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=86727&r1=86726&r2=86727&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Tue Nov 10 16:05:35 2009 @@ -623,12 +623,12 @@ void InsertRegionEnd(DIDescriptor D, BasicBlock *BB); /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call. - void InsertDeclare(llvm::Value *Storage, DIVariable D, - BasicBlock *InsertAtEnd); + Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D, + BasicBlock *InsertAtEnd); /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call. - void InsertDeclare(llvm::Value *Storage, DIVariable D, - Instruction *InsertBefore); + Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D, + Instruction *InsertBefore); private: Constant *GetTagConstant(unsigned TAG); @@ -731,6 +731,9 @@ /// processDeclare - Process DbgDeclareInst. void processDeclare(DbgDeclareInst *DDI); + /// processLocation - Process DILocation. + void processLocation(DILocation Loc); + /// addCompileUnit - Add compile unit into CUs. bool addCompileUnit(DICompileUnit CU); Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=86727&r1=86726&r2=86727&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Tue Nov 10 16:05:35 2009 @@ -1036,7 +1036,7 @@ } /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call. -void DIFactory::InsertDeclare(Value *Storage, DIVariable D, +Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D, Instruction *InsertBefore) { // Cast the storage to a {}* for the call to llvm.dbg.declare. Storage = new BitCastInst(Storage, EmptyStructPtr, "", InsertBefore); @@ -1045,11 +1045,11 @@ DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); Value *Args[] = { Storage, D.getNode() }; - CallInst::Create(DeclareFn, Args, Args+2, "", InsertBefore); + return CallInst::Create(DeclareFn, Args, Args+2, "", InsertBefore); } /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call. -void DIFactory::InsertDeclare(Value *Storage, DIVariable D, +Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D, BasicBlock *InsertAtEnd) { // Cast the storage to a {}* for the call to llvm.dbg.declare. Storage = new BitCastInst(Storage, EmptyStructPtr, "", InsertAtEnd); @@ -1058,7 +1058,7 @@ DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); Value *Args[] = { Storage, D.getNode() }; - CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd); + return CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd); } @@ -1088,18 +1088,9 @@ else if (DbgDeclareInst *DDI = dyn_cast(BI)) processDeclare(DDI); #ifdef ATTACH_DEBUG_INFO_TO_AN_INSN - else if (MDDbgKind) { - if (MDNode *L = TheMetadata.getMD(MDDbgKind, BI)) { - DILocation Loc(L); - DIScope S(Loc.getScope().getNode()); - if (S.isCompileUnit()) - addCompileUnit(DICompileUnit(S.getNode())); - else if (S.isSubprogram()) - processSubprogram(DISubprogram(S.getNode())); - else if (S.isLexicalBlock()) - processLexicalBlock(DILexicalBlock(S.getNode())); - } - } + else if (MDDbgKind) + if (MDNode *L = TheMetadata.getMD(MDDbgKind, BI)) + processLocation(DILocation(L)); #endif } @@ -1116,6 +1107,20 @@ } } +/// processLocation - Process DILocation. +void DebugInfoFinder::processLocation(DILocation Loc) { + if (Loc.isNull()) return; + DIScope S(Loc.getScope().getNode()); + if (S.isNull()) return; + if (S.isCompileUnit()) + addCompileUnit(DICompileUnit(S.getNode())); + else if (S.isSubprogram()) + processSubprogram(DISubprogram(S.getNode())); + else if (S.isLexicalBlock()) + processLexicalBlock(DILexicalBlock(S.getNode())); + processLocation(Loc.getOrigLocation()); +} + /// processType - Process DIType. void DebugInfoFinder::processType(DIType DT) { if (!addType(DT)) From clattner at apple.com Tue Nov 10 16:05:54 2009 From: clattner at apple.com (Chris Lattner) Date: Tue, 10 Nov 2009 14:05:54 -0800 Subject: [llvm-commits] [llvm] r86525 - /llvm/trunk/lib/VMCore/Instructions.cpp In-Reply-To: <745D848F-B85D-4F45-B265-EABAD791A9AC@apple.com> References: <200911090712.nA97C1pV013033@zion.cs.uiuc.edu> <745D848F-B85D-4F45-B265-EABAD791A9AC@apple.com> Message-ID: <9007D5DF-BE6E-4FC1-86DA-8BAC1C6BDBDB@apple.com> thanks! On Nov 10, 2009, at 11:54 AM, Victor Hernandez wrote: > I just realized that this patch only fixed this for CreateFree(), but > it also needs to be fixed in CreateMalloc(). > Fixed CreateMalloc() in r86712. > > Victor > > On Nov 8, 2009, at 11:12 PM, Chris Lattner wrote: > >> Author: lattner >> Date: Mon Nov 9 01:12:01 2009 >> New Revision: 86525 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=86525&view=rev >> Log: >> make this handle redefinition of malloc with different prototype >> correctly. >> >> Modified: >> llvm/trunk/lib/VMCore/Instructions.cpp >> >> Modified: llvm/trunk/lib/VMCore/Instructions.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=86525&r1=86524&r2=86525&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/VMCore/Instructions.cpp (original) >> +++ llvm/trunk/lib/VMCore/Instructions.cpp Mon Nov 9 01:12:01 2009 >> @@ -568,8 +568,7 @@ >> const Type *VoidTy = Type::getVoidTy(M->getContext()); >> const Type *IntPtrTy = Type::getInt8PtrTy(M->getContext()); >> // prototype free as "void free(void*)" >> - Function *FreeFunc = cast(M->getOrInsertFunction >> ("free", VoidTy, >> - >> IntPtrTy, NULL)); >> + Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, >> IntPtrTy, NULL); >> CallInst* Result = NULL; >> Value *PtrCast = Source; >> if (InsertBefore) { >> @@ -582,7 +581,8 @@ >> Result = CallInst::Create(FreeFunc, PtrCast, ""); >> } >> Result->setTailCall(); >> - Result->setCallingConv(FreeFunc->getCallingConv()); >> + if (Function *F = dyn_cast(FreeFunc)) >> + Result->setCallingConv(F->getCallingConv()); >> >> return Result; >> } >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Tue Nov 10 16:14:05 2009 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 10 Nov 2009 22:14:05 -0000 Subject: [llvm-commits] [llvm] r86729 - in /llvm/trunk: lib/Target/PowerPC/PPCRegisterInfo.cpp test/CodeGen/PowerPC/ppc-prologue.ll Message-ID: <200911102214.nAAME5Dk004068@zion.cs.uiuc.edu> Author: void Date: Tue Nov 10 16:14:04 2009 New Revision: 86729 URL: http://llvm.org/viewvc/llvm-project?rev=86729&view=rev Log: Modify how the prologue encoded the "move" information for the FDE. GCC generates a sequence similar to this: __Z4funci: LFB2: mflr r0 LCFI0: stmw r30,-8(r1) LCFI1: stw r0,8(r1) LCFI2: stwu r1,-80(r1) LCFI3: mr r30,r1 LCFI4: where LCFI3 and LCFI4 are used by the FDE to indicate what the FP, LR, and other things are. We generated something more like this: Leh_func_begin1: mflr r0 stw r31, 20(r1) stw r0, 8(r1) Llabel1: stwu r1, -80(r1) Llabel2: mr r31, r1 Note that we are missing the "mr" instruction. This patch makes it more like the GCC output. Added: llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=86729&r1=86728&r2=86729&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Tue Nov 10 16:14:04 2009 @@ -1356,12 +1356,6 @@ unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); unsigned MaxAlign = MFI->getMaxAlignment(); - if (needsFrameMoves) { - // Mark effective beginning of when frame pointer becomes valid. - FrameLabelId = MMI->NextLabelID(); - BuildMI(MBB, MBBI, dl, TII.get(PPC::DBG_LABEL)).addImm(FrameLabelId); - } - // Adjust stack pointer: r1 += NegFrameSize. // If there is a preferred stack alignment, align R1 now if (!IsPPC64) { @@ -1431,12 +1425,18 @@ .addReg(PPC::X0); } } + + std::vector &Moves = MMI->getFrameMoves(); + // Add the "machine moves" for the instructions we generated above, but in + // reverse order. if (needsFrameMoves) { - std::vector &Moves = MMI->getFrameMoves(); - + // Mark effective beginning of when frame pointer becomes valid. + FrameLabelId = MMI->NextLabelID(); + BuildMI(MBB, MBBI, dl, TII.get(PPC::DBG_LABEL)).addImm(FrameLabelId); + + // Show update of SP. if (NegFrameSize) { - // Show update of SP. MachineLocation SPDst(MachineLocation::VirtualFP); MachineLocation SPSrc(MachineLocation::VirtualFP, NegFrameSize); Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); @@ -1451,31 +1451,15 @@ Moves.push_back(MachineMove(FrameLabelId, FPDst, FPSrc)); } - // Add callee saved registers to move list. - const std::vector &CSI = MFI->getCalleeSavedInfo(); - for (unsigned I = 0, E = CSI.size(); I != E; ++I) { - int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); - unsigned Reg = CSI[I].getReg(); - if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue; - MachineLocation CSDst(MachineLocation::VirtualFP, Offset); - MachineLocation CSSrc(Reg); - Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc)); + if (MustSaveLR) { + MachineLocation LRDst(MachineLocation::VirtualFP, LROffset); + MachineLocation LRSrc(IsPPC64 ? PPC::LR8 : PPC::LR); + Moves.push_back(MachineMove(FrameLabelId, LRDst, LRSrc)); } - - MachineLocation LRDst(MachineLocation::VirtualFP, LROffset); - MachineLocation LRSrc(IsPPC64 ? PPC::LR8 : PPC::LR); - Moves.push_back(MachineMove(FrameLabelId, LRDst, LRSrc)); - - // Mark effective beginning of when frame pointer is ready. - unsigned ReadyLabelId = MMI->NextLabelID(); - BuildMI(MBB, MBBI, dl, TII.get(PPC::DBG_LABEL)).addImm(ReadyLabelId); - - MachineLocation FPDst(HasFP ? (IsPPC64 ? PPC::X31 : PPC::R31) : - (IsPPC64 ? PPC::X1 : PPC::R1)); - MachineLocation FPSrc(MachineLocation::VirtualFP); - Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc)); } + unsigned ReadyLabelId = 0; + // If there is a frame pointer, copy R1 into R31 if (HasFP) { if (!IsPPC64) { @@ -1487,6 +1471,33 @@ .addReg(PPC::X1) .addReg(PPC::X1); } + + if (needsFrameMoves) { + ReadyLabelId = MMI->NextLabelID(); + + // Mark effective beginning of when frame pointer is ready. + BuildMI(MBB, MBBI, dl, TII.get(PPC::DBG_LABEL)).addImm(ReadyLabelId); + + MachineLocation FPDst(HasFP ? (IsPPC64 ? PPC::X31 : PPC::R31) : + (IsPPC64 ? PPC::X1 : PPC::R1)); + MachineLocation FPSrc(MachineLocation::VirtualFP); + Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc)); + } + } + + if (needsFrameMoves) { + unsigned LabelId = HasFP ? ReadyLabelId : FrameLabelId; + + // Add callee saved registers to move list. + const std::vector &CSI = MFI->getCalleeSavedInfo(); + for (unsigned I = 0, E = CSI.size(); I != E; ++I) { + int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); + unsigned Reg = CSI[I].getReg(); + if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue; + MachineLocation CSDst(MachineLocation::VirtualFP, Offset); + MachineLocation CSSrc(Reg); + Moves.push_back(MachineMove(LabelId, CSDst, CSSrc)); + } } } Added: llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll?rev=86729&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll (added) +++ llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll Tue Nov 10 16:14:04 2009 @@ -0,0 +1,28 @@ +; RUN: llc < %s -march=ppc32 -disable-fp-elim | FileCheck %s + +define i32 @_Z4funci(i32 %a) ssp { +; CHECK: mflr r0 +; CHECK-NEXT: stw r31, 20(r1) +; CHECK-NEXT: stw r0, 8(r1) +; CHECK-NEXT: stwu r1, -80(r1) +; CHECK-NEXT: Llabel1: +; CHECK-NEXT: mr r31, r1 +; CHECK-NEXT: Llabel2: +entry: + %a_addr = alloca i32 ; [#uses=2] + %retval = alloca i32 ; [#uses=2] + %0 = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i32 %a, i32* %a_addr + %1 = call i32 @_Z3barPi(i32* %a_addr) ; [#uses=1] + store i32 %1, i32* %0, align 4 + %2 = load i32* %0, align 4 ; [#uses=1] + store i32 %2, i32* %retval, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; [#uses=1] + ret i32 %retval1 +} + +declare i32 @_Z3barPi(i32*) From gohman at apple.com Tue Nov 10 16:16:58 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 10 Nov 2009 22:16:58 -0000 Subject: [llvm-commits] [llvm] r86732 - /llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Message-ID: <200911102216.nAAMGwju004195@zion.cs.uiuc.edu> Author: djg Date: Tue Nov 10 16:16:57 2009 New Revision: 86732 URL: http://llvm.org/viewvc/llvm-project?rev=86732&view=rev Log: Don't mark conditional branch instructions as control barriers. Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=86732&r1=86731&r2=86732&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Tue Nov 10 16:16:57 2009 @@ -3601,21 +3601,23 @@ (BRASL texternalsym:$func)>; // Unconditional branches: -let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in { - def BR : - UncondBranch<0b001001100, (outs), (ins brtarget:$dest), - "br\t$dest", - [(br bb:$dest)]>; - - // Unconditional, absolute address branch - def BRA: - UncondBranch<0b001100000, (outs), (ins brtarget:$dest), - "bra\t$dest", - [/* no pattern */]>; - - // Indirect branch - def BI: - BIForm<0b00010101100, "bi\t$func", [(brind R32C:$func)]>; +let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in { + let isBarrier = 1 in { + def BR : + UncondBranch<0b001001100, (outs), (ins brtarget:$dest), + "br\t$dest", + [(br bb:$dest)]>; + + // Unconditional, absolute address branch + def BRA: + UncondBranch<0b001100000, (outs), (ins brtarget:$dest), + "bra\t$dest", + [/* no pattern */]>; + + // Indirect branch + def BI: + BIForm<0b00010101100, "bi\t$func", [(brind R32C:$func)]>; + } // Conditional branches: class BRNZInst pattern>: From dpatel at apple.com Tue Nov 10 16:23:59 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 10 Nov 2009 22:23:59 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r86734 - /llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Message-ID: <200911102223.nAAMNxhD004436@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 10 16:23:59 2009 New Revision: 86734 URL: http://llvm.org/viewvc/llvm-project?rev=86734&view=rev Log: Use "" as input file name if stdin is input source. Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=86734&r1=86733&r2=86734&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Tue Nov 10 16:23:59 2009 @@ -934,15 +934,22 @@ // code generator accepts maximum one main compile unit per module. If a // module does not contain any main compile unit then the code generator // will emit multiple compile units in the output object file. - getOrCreateCompileUnit(main_input_filename, true); + if (!strcmp (main_input_filename, "")) + getOrCreateCompileUnit("", true); + else + getOrCreateCompileUnit(main_input_filename, true); } /// getOrCreateCompileUnit - Get the compile unit from the cache or /// create a new one if necessary. DICompileUnit DebugInfo::getOrCreateCompileUnit(const char *FullPath, bool isMain) { - if (!FullPath) - FullPath = main_input_filename; + if (!FullPath) { + if (!strcmp (main_input_filename, "")) + FullPath = ""; + else + FullPath = main_input_filename; + } std::map::iterator I = CUCache.find(FullPath); if (I != CUCache.end()) if (Value *M = I->second) From sabre at nondot.org Tue Nov 10 16:26:15 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 22:26:15 -0000 Subject: [llvm-commits] [llvm] r86735 - in /llvm/trunk: include/llvm/Analysis/InstructionSimplify.h include/llvm/Transforms/Utils/Local.h lib/Analysis/InstructionSimplify.cpp lib/Transforms/Scalar/JumpThreading.cpp lib/Transforms/Utils/Local.cpp Message-ID: <200911102226.nAAMQFp1004527@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 16:26:15 2009 New Revision: 86735 URL: http://llvm.org/viewvc/llvm-project?rev=86735&view=rev Log: move some generally useful functions out of jump threading into libanalysis and transformutils. Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h llvm/trunk/include/llvm/Transforms/Utils/Local.h llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionSimplify.h?rev=86735&r1=86734&r2=86735&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h (original) +++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Tue Nov 10 16:26:15 2009 @@ -59,6 +59,15 @@ /// instruction. If not, this returns null. Value *SimplifyInstruction(Instruction *I, const TargetData *TD = 0); + + /// ReplaceAndSimplifyAllUses - Perform From->replaceAllUsesWith(To) and then + /// delete the From instruction. In addition to a basic RAUW, this does a + /// recursive simplification of the updated instructions. This catches + /// things where one simplification exposes other opportunities. This only + /// simplifies and deletes scalar operations, it does not change the CFG. + /// + void ReplaceAndSimplifyAllUses(Instruction *From, Value *To, + const TargetData *TD = 0); } // end namespace llvm #endif Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=86735&r1=86734&r2=86735&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Tue Nov 10 16:26:15 2009 @@ -78,6 +78,21 @@ // Control Flow Graph Restructuring. // +/// RemovePredecessorAndSimplify - Like BasicBlock::removePredecessor, this +/// method is called when we're about to delete Pred as a predecessor of BB. If +/// BB contains any PHI nodes, this drops the entries in the PHI nodes for Pred. +/// +/// Unlike the removePredecessor method, this attempts to simplify uses of PHI +/// nodes that collapse into identity values. For example, if we have: +/// x = phi(1, 0, 0, 0) +/// y = and x, z +/// +/// .. and delete the predecessor corresponding to the '1', this will attempt to +/// recursively fold the 'and' to 0. +void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred, + TargetData *TD = 0); + + /// MergeBasicBlockIntoOnlyPred - BB is a block with one predecessor and its /// predecessor is known to have one successor (BB!). Eliminate the edge /// between them, moving the instructions in the predecessor into BB. This Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=86735&r1=86734&r2=86735&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Tue Nov 10 16:26:15 2009 @@ -15,6 +15,7 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Support/ValueHandle.h" #include "llvm/Instructions.h" #include "llvm/Support/PatternMatch.h" using namespace llvm; @@ -311,3 +312,37 @@ } } +/// ReplaceAndSimplifyAllUses - Perform From->replaceAllUsesWith(To) and then +/// delete the From instruction. In addition to a basic RAUW, this does a +/// recursive simplification of the newly formed instructions. This catches +/// things where one simplification exposes other opportunities. This only +/// simplifies and deletes scalar operations, it does not change the CFG. +/// +void llvm::ReplaceAndSimplifyAllUses(Instruction *From, Value *To, + const TargetData *TD) { + assert(From != To && "ReplaceAndSimplifyAllUses(X,X) is not valid!"); + + // FromHandle - This keeps a weakvh on the from value so that we can know if + // it gets deleted out from under us in a recursive simplification. + WeakVH FromHandle(From); + + while (!From->use_empty()) { + // Update the instruction to use the new value. + Use &U = From->use_begin().getUse(); + Instruction *User = cast(U.getUser()); + U = To; + + // See if we can simplify it. + if (Value *V = SimplifyInstruction(User, TD)) { + // Recursively simplify this. + ReplaceAndSimplifyAllUses(User, V, TD); + + // If the recursive simplification ended up revisiting and deleting 'From' + // then we're done. + if (FromHandle == 0) + return; + } + } + From->eraseFromParent(); +} + Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86735&r1=86734&r2=86735&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Tue Nov 10 16:26:15 2009 @@ -203,89 +203,6 @@ return Size; } - -//===----------------------------------------------------------------------===// - -/// ReplaceAndSimplifyAllUses - Perform From->replaceAllUsesWith(To) and then -/// delete the From instruction. In addition to a basic RAUW, this does a -/// recursive simplification of the newly formed instructions. This catches -/// things where one simplification exposes other opportunities. This only -/// simplifies and deletes scalar operations, it does not change the CFG. -/// -static void ReplaceAndSimplifyAllUses(Instruction *From, Value *To, - const TargetData *TD) { - assert(From != To && "ReplaceAndSimplifyAllUses(X,X) is not valid!"); - - // FromHandle - This keeps a weakvh on the from value so that we can know if - // it gets deleted out from under us in a recursive simplification. - WeakVH FromHandle(From); - - while (!From->use_empty()) { - // Update the instruction to use the new value. - Use &U = From->use_begin().getUse(); - Instruction *User = cast(U.getUser()); - U = To; - - // See if we can simplify it. - if (Value *V = SimplifyInstruction(User, TD)) { - // Recursively simplify this. - ReplaceAndSimplifyAllUses(User, V, TD); - - // If the recursive simplification ended up revisiting and deleting 'From' - // then we're done. - if (FromHandle == 0) - return; - } - } - From->eraseFromParent(); -} - - -/// RemovePredecessorAndSimplify - Like BasicBlock::removePredecessor, this -/// method is called when we're about to delete Pred as a predecessor of BB. If -/// BB contains any PHI nodes, this drops the entries in the PHI nodes for Pred. -/// -/// Unlike the removePredecessor method, this attempts to simplify uses of PHI -/// nodes that collapse into identity values. For example, if we have: -/// x = phi(1, 0, 0, 0) -/// y = and x, z -/// -/// .. and delete the predecessor corresponding to the '1', this will attempt to -/// recursively fold the and to 0. -static void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred, - TargetData *TD) { - // This only adjusts blocks with PHI nodes. - if (!isa(BB->begin())) - return; - - // Remove the entries for Pred from the PHI nodes in BB, but do not simplify - // them down. This will leave us with single entry phi nodes and other phis - // that can be removed. - BB->removePredecessor(Pred, true); - - WeakVH PhiIt = &BB->front(); - while (PHINode *PN = dyn_cast(PhiIt)) { - PhiIt = &*++BasicBlock::iterator(cast(PhiIt)); - - Value *PNV = PN->hasConstantValue(); - if (PNV == 0) continue; - - // If we're able to simplify the phi to a single value, substitute the new - // value into all of its uses. - assert(PNV != PN && "hasConstantValue broken"); - - ReplaceAndSimplifyAllUses(PN, PNV, TD); - - // If recursive simplification ended up deleting the next PHI node we would - // iterate to, then our iterator is invalid, restart scanning from the top - // of the block. - if (PhiIt == 0) PhiIt = &BB->front(); - } -} - -//===----------------------------------------------------------------------===// - - /// FindLoopHeaders - We do not want jump threading to turn proper loop /// structures into irreducible loops. Doing this breaks up the loop nesting /// hierarchy and pessimizes later transformations. To prevent this from Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=86735&r1=86734&r2=86735&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Tue Nov 10 16:26:15 2009 @@ -24,6 +24,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/DebugInfo.h" +#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/CFG.h" @@ -239,7 +240,7 @@ //===----------------------------------------------------------------------===// -// Local dead code elimination... +// Local dead code elimination. // /// isInstructionTriviallyDead - Return true if the result produced by the @@ -326,9 +327,53 @@ } //===----------------------------------------------------------------------===// -// Control Flow Graph Restructuring... +// Control Flow Graph Restructuring. // + +/// RemovePredecessorAndSimplify - Like BasicBlock::removePredecessor, this +/// method is called when we're about to delete Pred as a predecessor of BB. If +/// BB contains any PHI nodes, this drops the entries in the PHI nodes for Pred. +/// +/// Unlike the removePredecessor method, this attempts to simplify uses of PHI +/// nodes that collapse into identity values. For example, if we have: +/// x = phi(1, 0, 0, 0) +/// y = and x, z +/// +/// .. and delete the predecessor corresponding to the '1', this will attempt to +/// recursively fold the and to 0. +void llvm::RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred, + TargetData *TD) { + // This only adjusts blocks with PHI nodes. + if (!isa(BB->begin())) + return; + + // Remove the entries for Pred from the PHI nodes in BB, but do not simplify + // them down. This will leave us with single entry phi nodes and other phis + // that can be removed. + BB->removePredecessor(Pred, true); + + WeakVH PhiIt = &BB->front(); + while (PHINode *PN = dyn_cast(PhiIt)) { + PhiIt = &*++BasicBlock::iterator(cast(PhiIt)); + + Value *PNV = PN->hasConstantValue(); + if (PNV == 0) continue; + + // If we're able to simplify the phi to a single value, substitute the new + // value into all of its uses. + assert(PNV != PN && "hasConstantValue broken"); + + ReplaceAndSimplifyAllUses(PN, PNV, TD); + + // If recursive simplification ended up deleting the next PHI node we would + // iterate to, then our iterator is invalid, restart scanning from the top + // of the block. + if (PhiIt == 0) PhiIt = &BB->front(); + } +} + + /// MergeBasicBlockIntoOnlyPred - DestBB is a block with one predecessor and its /// predecessor is known to have one successor (DestBB!). Eliminate the edge /// between them, moving the instructions in the predecessor into DestBB and From sabre at nondot.org Tue Nov 10 16:39:17 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 22:39:17 -0000 Subject: [llvm-commits] [llvm] r86739 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/basic.ll Message-ID: <200911102239.nAAMdHpr005071@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 16:39:16 2009 New Revision: 86739 URL: http://llvm.org/viewvc/llvm-project?rev=86739&view=rev Log: implement a TODO by teaching jump threading about "xor x, 1". Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp llvm/trunk/test/Transforms/JumpThreading/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86739&r1=86738&r2=86739&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Tue Nov 10 16:39:16 2009 @@ -299,8 +299,20 @@ return !Result.empty(); } - // TODO: Should handle the NOT form of XOR. - + // Handle the NOT form of XOR. + if (I->getOpcode() == Instruction::Xor && + isa(I->getOperand(1)) && + cast(I->getOperand(1))->isOne()) { + ComputeValueKnownInPredecessors(I->getOperand(0), BB, Result); + if (Result.empty()) + return false; + + // Invert the known values. + for (unsigned i = 0, e = Result.size(); i != e; ++i) + Result[i].first = + cast(ConstantExpr::getNot(Result[i].first)); + return true; + } } // Handle compare with phi operand, where the PHI is defined in this block. Modified: llvm/trunk/test/Transforms/JumpThreading/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/basic.ll?rev=86739&r1=86738&r2=86739&view=diff ============================================================================== --- llvm/trunk/test/Transforms/JumpThreading/basic.ll (original) +++ llvm/trunk/test/Transforms/JumpThreading/basic.ll Tue Nov 10 16:39:16 2009 @@ -245,3 +245,42 @@ ret i32 2 } + +;;; Verify that we can handle constraint propagation through "xor x, 1". +define i32 @test9(i1 %cond, i1 %cond2) { +Entry: +; CHECK: @test9 + %v1 = call i32 @f1() + br i1 %cond, label %Merge, label %F1 + +; CHECK: Entry: +; CHECK-NEXT: %v1 = call i32 @f1() +; CHECK-NEXT: br i1 %cond, label %F2, label %Merge + +F1: + %v2 = call i32 @f2() + br label %Merge + +Merge: + %B = phi i32 [%v1, %Entry], [%v2, %F1] + %M = icmp eq i32 %B, %v1 + %M1 = xor i1 %M, 1 + %N = icmp eq i32 %B, 47 + %O = and i1 %M1, %N + br i1 %O, label %T2, label %F2 + +; CHECK: Merge: +; CHECK-NOT: phi +; CHECK-NEXT: %v2 = call i32 @f2() + +T2: + %Q = zext i1 %M to i32 + ret i32 %Q + +F2: + ret i32 %B +; CHECK: F2: +; CHECK-NEXT: phi i32 +} + + From wendling at apple.com Tue Nov 10 16:39:36 2009 From: wendling at apple.com (Bill Wendling) Date: Tue, 10 Nov 2009 14:39:36 -0800 Subject: [llvm-commits] [llvm] r86729 - in /llvm/trunk: lib/Target/PowerPC/PPCRegisterInfo.cpp test/CodeGen/PowerPC/ppc-prologue.ll In-Reply-To: <200911102214.nAAME5Dk004068@zion.cs.uiuc.edu> References: <200911102214.nAAME5Dk004068@zion.cs.uiuc.edu> Message-ID: <343771B2-2B31-4D1C-B5C1-1F935FCBF808@apple.com> On Nov 10, 2009, at 2:14 PM, Bill Wendling wrote: > Author: void > Date: Tue Nov 10 16:14:04 2009 > New Revision: 86729 > > URL: http://llvm.org/viewvc/llvm-project?rev=86729&view=rev > Log: > Modify how the prologue encoded the "move" information for the FDE. > GCC > generates a sequence similar to this: > > __Z4funci: > LFB2: > mflr r0 > LCFI0: > stmw r30,-8(r1) > LCFI1: > stw r0,8(r1) > LCFI2: > stwu r1,-80(r1) > LCFI3: > mr r30,r1 > LCFI4: > > where LCFI3 and LCFI4 are used by the FDE to indicate what the FP, > LR, and other > things are. We generated something more like this: > > Leh_func_begin1: > mflr r0 > stw r31, 20(r1) > stw r0, 8(r1) > Llabel1: > stwu r1, -80(r1) > Llabel2: > mr r31, r1 > > Note that we are missing the "mr" instruction. This patch makes it > more like the > GCC output. A clarification: I don't mean that the mr instruction wasn't in the original output, but only that it wasn't properly reported in the FDE. -bw From vkutuzov at accesssoftek.com Tue Nov 10 16:47:23 2009 From: vkutuzov at accesssoftek.com (Viktor Kutuzov) Date: Tue, 10 Nov 2009 14:47:23 -0800 Subject: [llvm-commits] [PATCH] LTO code generator options: --verbose References: <6AE1604EE3EC5F4296C096518C6B77EEF99C4FAA@mail.accesssoftek.com> <7383326612F04B4DA85C26A2C9A4E6D4@andreic6e7fe55> <4C3AAB5F-812D-4811-A1EE-DEF04E0F29EE@apple.com> Message-ID: <214DD1AE30F746F5B0086F4773D23D32@andreic6e7fe55> Please find attached the patch without cosmetic changes. Best regards, Viktor ----- Original Message ----- From: "Eric Christopher" To: "Viktor Kutuzov" Cc: "Commit Messages and Patches for LLVM" Sent: Tuesday, November 10, 2009 1:15 PM Subject: Re: [llvm-commits] [PATCH] LTO code generator options: --verbose On Nov 10, 2009, at 1:10 PM, Viktor Kutuzov wrote: > It'd be easier to look at if there were less cosmetic changes in the patch. That said, what do you expect this will add? -eric -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-lto-codegen_verbose.diff Type: application/octet-stream Size: 3574 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091110/a89dbc1a/attachment.obj From sabre at nondot.org Tue Nov 10 16:56:15 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 22:56:15 -0000 Subject: [llvm-commits] [llvm] r86747 - /llvm/trunk/include/llvm/Analysis/CFGPrinter.h Message-ID: <200911102256.nAAMuFFZ006044@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 16:56:15 2009 New Revision: 86747 URL: http://llvm.org/viewvc/llvm-project?rev=86747&view=rev Log: in -dot-cfg and -dot-cfg-only, when rendering switch instructions, put the switch value in the successor boxes like we put T/F for branches. Modified: llvm/trunk/include/llvm/Analysis/CFGPrinter.h Modified: llvm/trunk/include/llvm/Analysis/CFGPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/CFGPrinter.h?rev=86747&r1=86746&r2=86747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/CFGPrinter.h (original) +++ llvm/trunk/include/llvm/Analysis/CFGPrinter.h Tue Nov 10 16:56:15 2009 @@ -71,6 +71,18 @@ if (const BranchInst *BI = dyn_cast(Node->getTerminator())) if (BI->isConditional()) return (I == succ_begin(Node)) ? "T" : "F"; + + // Label source of conditional branches with "T" or "F" + if (const SwitchInst *SI = dyn_cast(Node->getTerminator())) { + unsigned SuccNo = I.getSuccessorIndex(); + + if (SuccNo == 0) return "def"; + + std::string Str; + raw_string_ostream OS(Str); + OS << SI->getCaseValue(SuccNo)->getValue(); + return OS.str(); + } return ""; } }; From dpatel at apple.com Tue Nov 10 17:06:00 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 10 Nov 2009 23:06:00 -0000 Subject: [llvm-commits] [llvm] r86748 - in /llvm/trunk: include/llvm/Analysis/ include/llvm/CodeGen/ include/llvm/Transforms/Utils/ lib/Analysis/ lib/CodeGen/AsmPrinter/ lib/CodeGen/SelectionDAG/ lib/Transforms/Utils/ Message-ID: <200911102306.nAAN61b2006429@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 10 17:06:00 2009 New Revision: 86748 URL: http://llvm.org/viewvc/llvm-project?rev=86748&view=rev Log: Implement support to debug inlined functions. Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h llvm/trunk/include/llvm/CodeGen/DwarfWriter.h llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h llvm/trunk/include/llvm/Transforms/Utils/Cloning.h llvm/trunk/lib/Analysis/DebugInfo.cpp llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Tue Nov 10 17:06:00 2009 @@ -693,12 +693,6 @@ DebugLoc ExtractDebugLocation(DbgFuncStartInst &FSI, DebugLocTracker &DebugLocInfo); - /// isInlinedFnStart - Return true if FSI is starting an inlined function. - bool isInlinedFnStart(DbgFuncStartInst &FSI, const Function *CurrentFn); - - /// isInlinedFnEnd - Return true if REI is ending an inlined function. - bool isInlinedFnEnd(DbgRegionEndInst &REI, const Function *CurrentFn); - /// DebugInfoFinder - This object collects DebugInfo from a module. class DebugInfoFinder { public: Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DwarfWriter.h?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/DwarfWriter.h (original) +++ llvm/trunk/include/llvm/CodeGen/DwarfWriter.h Tue Nov 10 17:06:00 2009 @@ -104,14 +104,8 @@ /// be emitted. bool ShouldEmitDwarfDebug() const; - //// RecordInlinedFnStart - Indicate the start of a inlined function. - unsigned RecordInlinedFnStart(DISubprogram SP, DICompileUnit CU, - unsigned Line, unsigned Col); - - /// RecordInlinedFnEnd - Indicate the end of inlined subroutine. - unsigned RecordInlinedFnEnd(DISubprogram SP); - void SetDbgScopeBeginLabels(const MachineInstr *MI, unsigned L); - void SetDbgScopeEndLabels(const MachineInstr *MI, unsigned L); + void BeginScope(const MachineInstr *MI, unsigned Label); + void EndScope(const MachineInstr *MI); }; } // end llvm namespace Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Tue Nov 10 17:06:00 2009 @@ -150,7 +150,8 @@ public: static char ID; // Pass identification, replacement for typeid - typedef SmallVector< std::pair, unsigned>, 4 > + typedef std::pair > UnsignedAndMDNodePair; + typedef SmallVector< std::pair, UnsignedAndMDNodePair>, 4> VariableDbgInfoMapTy; VariableDbgInfoMapTy VariableDbgInfo; @@ -336,8 +337,8 @@ /// setVariableDbgInfo - Collect information used to emit debugging information /// of a variable. - void setVariableDbgInfo(MDNode *N, unsigned S) { - VariableDbgInfo.push_back(std::make_pair(N, S)); + void setVariableDbgInfo(MDNode *N, unsigned Slot, MDNode *Scope) { + VariableDbgInfo.push_back(std::make_pair(N, std::make_pair(Slot, Scope))); } VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfo; } Modified: llvm/trunk/include/llvm/Transforms/Utils/Cloning.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Cloning.h?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Cloning.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Cloning.h Tue Nov 10 17:06:00 2009 @@ -24,6 +24,7 @@ class Module; class Function; +class Instruction; class Pass; class LPPassManager; class BasicBlock; @@ -154,7 +155,8 @@ SmallVectorImpl &Returns, const char *NameSuffix = "", ClonedCodeInfo *CodeInfo = 0, - const TargetData *TD = 0); + const TargetData *TD = 0, + Instruction *TheCall = 0); /// InlineFunction - This function inlines the called function into the basic /// block of the caller. This returns false if it is not possible to inline Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Tue Nov 10 17:06:00 2009 @@ -1487,22 +1487,4 @@ return DebugLoc::get(Id); } - - /// isInlinedFnStart - Return true if FSI is starting an inlined function. - bool isInlinedFnStart(DbgFuncStartInst &FSI, const Function *CurrentFn) { - DISubprogram Subprogram(cast(FSI.getSubprogram())); - if (Subprogram.describes(CurrentFn)) - return false; - - return true; - } - - /// isInlinedFnEnd - Return true if REI is ending an inlined function. - bool isInlinedFnEnd(DbgRegionEndInst &REI, const Function *CurrentFn) { - DISubprogram Subprogram(cast(REI.getContext())); - if (Subprogram.isNull() || Subprogram.describes(CurrentFn)) - return false; - - return true; - } } Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Tue Nov 10 17:06:00 2009 @@ -1357,32 +1357,31 @@ /// instruction's DebugLoc. void AsmPrinter::processDebugLoc(const MachineInstr *MI, bool BeforePrintingInsn) { - if (!MAI || !DW) + if (!MAI || !DW || !MAI->doesSupportDebugInformation() + || !DW->ShouldEmitDwarfDebug()) return; DebugLoc DL = MI->getDebugLoc(); - if (MAI->doesSupportDebugInformation() && DW->ShouldEmitDwarfDebug()) { - if (!DL.isUnknown()) { - DebugLocTuple CurDLT = MF->getDebugLocTuple(DL); - if (BeforePrintingInsn) { - if (CurDLT.Scope != 0 && PrevDLT != CurDLT) { - unsigned L = DW->RecordSourceLine(CurDLT.Line, CurDLT.Col, - CurDLT.Scope); - printLabel(L); - O << '\n'; -#ifdef ATTACH_DEBUG_INFO_TO_AN_INSN - DW->SetDbgScopeBeginLabels(MI, L); -#endif - } else { -#ifdef ATTACH_DEBUG_INFO_TO_AN_INSN - DW->SetDbgScopeEndLabels(MI, 0); -#endif - } - } + if (DL.isUnknown()) + return; + DebugLocTuple CurDLT = MF->getDebugLocTuple(DL); + if (CurDLT.Scope == 0) + return; + + if (BeforePrintingInsn) { + if (CurDLT != PrevDLT) { + unsigned L = DW->RecordSourceLine(CurDLT.Line, CurDLT.Col, + CurDLT.Scope); + printLabel(L); + DW->BeginScope(MI, L); PrevDLT = CurDLT; } + } else { + // After printing instruction + DW->EndScope(MI); } } + /// printInlineAsm - This method formats and prints the specified machine /// instruction that is an inline asm. void AsmPrinter::printInlineAsm(const MachineInstr *MI) const { Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Nov 10 17:06:00 2009 @@ -127,15 +127,19 @@ class DbgVariable { DIVariable Var; // Variable Descriptor. unsigned FrameIndex; // Variable frame index. - bool InlinedFnVar; // Variable for an inlined function. + DbgVariable *AbstractVar; // Abstract variable for this variable. + DIE *TheDIE; public: - DbgVariable(DIVariable V, unsigned I, bool IFV) - : Var(V), FrameIndex(I), InlinedFnVar(IFV) {} + DbgVariable(DIVariable V, unsigned I) + : Var(V), FrameIndex(I), AbstractVar(0), TheDIE(0) {} // Accessors. - DIVariable getVariable() const { return Var; } - unsigned getFrameIndex() const { return FrameIndex; } - bool isInlinedFnVar() const { return InlinedFnVar; } + DIVariable getVariable() const { return Var; } + unsigned getFrameIndex() const { return FrameIndex; } + void setAbstractVariable(DbgVariable *V) { AbstractVar = V; } + DbgVariable *getAbstractVariable() const { return AbstractVar; } + void setDIE(DIE *D) { TheDIE = D; } + DIE *getDIE() const { return TheDIE; } }; //===----------------------------------------------------------------------===// @@ -144,44 +148,46 @@ class DbgConcreteScope; class DbgScope { DbgScope *Parent; // Parent to this scope. - DIDescriptor Desc; // Debug info descriptor for scope. - // FIXME use WeakVH for Desc. - WeakVH InlinedAt; // If this scope represents inlined - // function body then this is the location - // where this body is inlined. + DIDescriptor Desc; // Debug info descriptor for scope. + WeakVH InlinedAtLocation; // Location at which scope is inlined. + bool AbstractScope; // Abstract Scope unsigned StartLabelID; // Label ID of the beginning of scope. unsigned EndLabelID; // Label ID of the end of scope. const MachineInstr *LastInsn; // Last instruction of this scope. const MachineInstr *FirstInsn; // First instruction of this scope. SmallVector Scopes; // Scopes defined in scope. SmallVector Variables;// Variables declared in scope. - SmallVector ConcreteInsts;// Concrete insts of funcs. // Private state for dump() mutable unsigned IndentLevel; public: DbgScope(DbgScope *P, DIDescriptor D, MDNode *I = 0) - : Parent(P), Desc(D), InlinedAt(I), StartLabelID(0), EndLabelID(0), + : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(false), + StartLabelID(0), EndLabelID(0), LastInsn(0), FirstInsn(0), IndentLevel(0) {} virtual ~DbgScope(); // Accessors. DbgScope *getParent() const { return Parent; } + void setParent(DbgScope *P) { Parent = P; } DIDescriptor getDesc() const { return Desc; } - MDNode *getInlinedAt() const { - return dyn_cast_or_null(InlinedAt); + MDNode *getInlinedAt() const { + return dyn_cast_or_null(InlinedAtLocation); } + MDNode *getScopeNode() const { return Desc.getNode(); } unsigned getStartLabelID() const { return StartLabelID; } unsigned getEndLabelID() const { return EndLabelID; } SmallVector &getScopes() { return Scopes; } SmallVector &getVariables() { return Variables; } - SmallVector &getConcreteInsts() { return ConcreteInsts; } void setStartLabelID(unsigned S) { StartLabelID = S; } void setEndLabelID(unsigned E) { EndLabelID = E; } void setLastInsn(const MachineInstr *MI) { LastInsn = MI; } const MachineInstr *getLastInsn() { return LastInsn; } void setFirstInsn(const MachineInstr *MI) { FirstInsn = MI; } + void setAbstractScope() { AbstractScope = true; } + bool isAbstractScope() const { return AbstractScope; } const MachineInstr *getFirstInsn() { return FirstInsn; } + /// AddScope - Add a scope to the scope. /// void AddScope(DbgScope *S) { Scopes.push_back(S); } @@ -190,10 +196,6 @@ /// void AddVariable(DbgVariable *V) { Variables.push_back(V); } - /// AddConcreteInst - Add a concrete instance to the scope. - /// - void AddConcreteInst(DbgConcreteScope *C) { ConcreteInsts.push_back(C); } - void FixInstructionMarkers() { assert (getFirstInsn() && "First instruction is missing!"); if (getLastInsn()) @@ -218,11 +220,15 @@ void DbgScope::dump() const { raw_ostream &err = errs(); err.indent(IndentLevel); - Desc.dump(); + MDNode *N = Desc.getNode(); + N->dump(); err << " [" << StartLabelID << ", " << EndLabelID << "]\n"; + if (AbstractScope) + err << "Abstract Scope\n"; IndentLevel += 2; - + if (!Scopes.empty()) + err << "Children ...\n"; for (unsigned i = 0, e = Scopes.size(); i != e; ++i) if (Scopes[i] != this) Scopes[i]->dump(); @@ -251,8 +257,6 @@ delete Scopes[i]; for (unsigned j = 0, M = Variables.size(); j < M; ++j) delete Variables[j]; - for (unsigned k = 0, O = ConcreteInsts.size(); k < O; ++k) - delete ConcreteInsts[k]; } } // end llvm namespace @@ -262,7 +266,7 @@ AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(), ValuesSet(InitValuesSetSize), Values(), StringPool(), SectionSourceLines(), didInitial(false), shouldEmit(false), - FunctionDbgScope(0), DebugTimer(0) { + CurrentFnDbgScope(0), DebugTimer(0) { if (TimePassesIsEnabled) DebugTimer = new Timer("Dwarf Debug Writer", getDwarfTimerGroup()); @@ -271,11 +275,6 @@ for (unsigned j = 0, M = Values.size(); j < M; ++j) delete Values[j]; - for (DenseMap::iterator - I = AbstractInstanceRootMap.begin(), - E = AbstractInstanceRootMap.end(); I != E;++I) - delete I->second; - delete DebugTimer; } @@ -1237,9 +1236,6 @@ } } - if (!SP.isLocalToUnit() && !IsInlined) - AddUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); - // DW_TAG_inlined_subroutine may refer to this DIE. DIE *&Slot = DW_Unit->getDieMapSlotFor(SP.getNode()); Slot = SPDie; @@ -1287,81 +1283,109 @@ AddSourceLine(VariableDie, &VD); // Add variable type. - // FIXME: isBlockByrefVariable should be reformulated in terms of complex addresses instead. + // FIXME: isBlockByrefVariable should be reformulated in terms of complex + // addresses instead. if (VD.isBlockByrefVariable()) AddType(Unit, VariableDie, GetBlockByrefType(VD.getType(), Name)); else AddType(Unit, VariableDie, VD.getType()); // Add variable address. - if (!DV->isInlinedFnVar()) { - // Variables for abstract instances of inlined functions don't get a - // location. - MachineLocation Location; - Location.set(RI->getFrameRegister(*MF), - RI->getFrameIndexOffset(*MF, DV->getFrameIndex())); - - - if (VD.hasComplexAddress()) - AddComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location); - else if (VD.isBlockByrefVariable()) - AddBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location); - else - AddAddress(VariableDie, dwarf::DW_AT_location, Location); - } + // Variables for abstract instances of inlined functions don't get a + // location. + MachineLocation Location; + Location.set(RI->getFrameRegister(*MF), + RI->getFrameIndexOffset(*MF, DV->getFrameIndex())); + + + if (VD.hasComplexAddress()) + AddComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location); + else if (VD.isBlockByrefVariable()) + AddBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location); + else + AddAddress(VariableDie, dwarf::DW_AT_location, Location); return VariableDie; } -/// getOrCreateScope - Returns the scope associated with the given descriptor. -/// -DbgScope *DwarfDebug::getDbgScope(MDNode *N, const MachineInstr *MI, - MDNode *InlinedAt) { - ValueMap::iterator VI = DbgScopeMap.find(N); - if (VI != DbgScopeMap.end()) - return VI->second; +/// getUpdatedDbgScope - Find or create DbgScope assicated with the instruction. +/// Initialize scope and update scope hierarchy. +DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI, + MDNode *InlinedAt) { + assert (N && "Invalid Scope encoding!"); + assert (MI && "Missing machine instruction!"); + bool GetConcreteScope = (MI && InlinedAt); - DbgScope *Parent = NULL; + DbgScope *NScope = NULL; + + if (InlinedAt) + NScope = DbgScopeMap.lookup(InlinedAt); + else + NScope = DbgScopeMap.lookup(N); + assert (NScope && "Unable to find working scope!"); + + if (NScope->getFirstInsn()) + return NScope; - if (InlinedAt) { + DbgScope *Parent = NULL; + if (GetConcreteScope) { DILocation IL(InlinedAt); - assert (!IL.isNull() && "Invalid InlindAt location!"); - ValueMap::iterator DSI = - DbgScopeMap.find(IL.getScope().getNode()); - assert (DSI != DbgScopeMap.end() && "Unable to find InlineAt scope!"); - Parent = DSI->second; - } else { - DIDescriptor Scope(N); - if (Scope.isCompileUnit()) { - return NULL; - } else if (Scope.isSubprogram()) { - DISubprogram SP(N); - DIDescriptor ParentDesc = SP.getContext(); - if (!ParentDesc.isNull() && !ParentDesc.isCompileUnit()) - Parent = getDbgScope(ParentDesc.getNode(), MI, InlinedAt); - } else if (Scope.isLexicalBlock()) { - DILexicalBlock DB(N); - DIDescriptor ParentDesc = DB.getContext(); - if (!ParentDesc.isNull()) - Parent = getDbgScope(ParentDesc.getNode(), MI, InlinedAt); - } else - assert (0 && "Unexpected scope info"); + Parent = getUpdatedDbgScope(IL.getScope().getNode(), MI, + IL.getOrigLocation().getNode()); + assert (Parent && "Unable to find Parent scope!"); + NScope->setParent(Parent); + Parent->AddScope(NScope); + } else if (DIDescriptor(N).isLexicalBlock()) { + DILexicalBlock DB(N); + if (!DB.getContext().isNull()) { + Parent = getUpdatedDbgScope(DB.getContext().getNode(), MI, InlinedAt); + NScope->setParent(Parent); + Parent->AddScope(NScope); + } } - DbgScope *NScope = new DbgScope(Parent, DIDescriptor(N), InlinedAt); NScope->setFirstInsn(MI); - if (Parent) - Parent->AddScope(NScope); - else - // First function is top level function. - if (!FunctionDbgScope) - FunctionDbgScope = NScope; + if (!Parent && !InlinedAt) { + assert (!CurrentFnDbgScope && "Unexpected function scope!"); + CurrentFnDbgScope = NScope; + } + + if (GetConcreteScope) { + ConcreteScopes[InlinedAt] = NScope; + getOrCreateAbstractScope(N); + } - DbgScopeMap.insert(std::make_pair(N, NScope)); return NScope; } +DbgScope *DwarfDebug::getOrCreateAbstractScope(MDNode *N) { + assert (N && "Invalid Scope encoding!"); + + DbgScope *AScope = AbstractScopes.lookup(N); + if (AScope) + return AScope; + + DbgScope *Parent = NULL; + + DIDescriptor Scope(N); + if (Scope.isLexicalBlock()) { + DILexicalBlock DB(N); + DIDescriptor ParentDesc = DB.getContext(); + if (!ParentDesc.isNull()) + Parent = getOrCreateAbstractScope(ParentDesc.getNode()); + } + + AScope = new DbgScope(Parent, DIDescriptor(N), NULL); + + if (Parent) + Parent->AddScope(AScope); + AScope->setAbstractScope(); + AbstractScopes[N] = AScope; + if (DIDescriptor(N).isSubprogram()) + AbstractScopesList.push_back(AScope); + return AScope; +} /// getOrCreateScope - Returns the scope associated with the given descriptor. /// FIXME - Remove this method. @@ -1372,12 +1396,6 @@ DbgScope *Parent = NULL; DILexicalBlock Block(N); - // Don't create a new scope if we already created one for an inlined function. - DenseMap::iterator - II = AbstractInstanceRootMap.find(N); - if (II != AbstractInstanceRootMap.end()) - return LexicalScopeStack.back(); - if (!Block.isNull()) { DIDescriptor ParentDesc = Block.getContext(); Parent = @@ -1390,13 +1408,241 @@ Parent->AddScope(Slot); else // First function is top level function. - FunctionDbgScope = Slot; + CurrentFnDbgScope = Slot; return Slot; } +static DISubprogram getDISubprogram(MDNode *N) { + + DIDescriptor D(N); + if (D.isNull()) + return DISubprogram(); + + if (D.isCompileUnit()) + return DISubprogram(); + + if (D.isSubprogram()) + return DISubprogram(N); + + if (D.isLexicalBlock()) + return getDISubprogram(DILexicalBlock(N).getContext().getNode()); + + llvm_unreachable("Unexpected Descriptor!"); +} + +DIE *DwarfDebug::UpdateSubprogramScopeDIE(MDNode *SPNode) { + + DIE *SPDie = ModuleCU->getDieMapSlotFor(SPNode); + assert (SPDie && "Unable to find subprogram DIE!"); + AddLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, + DWLabel("func_begin", SubprogramCount)); + AddLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, + DWLabel("func_end", SubprogramCount)); + MachineLocation Location(RI->getFrameRegister(*MF)); + AddAddress(SPDie, dwarf::DW_AT_frame_base, Location); + + if (!DISubprogram(SPNode).isLocalToUnit()) + AddUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); + + // If there are global variables at this scope then add their dies. + for (SmallVector::iterator SGI = ScopedGVs.begin(), + SGE = ScopedGVs.end(); SGI != SGE; ++SGI) { + MDNode *N = dyn_cast_or_null(*SGI); + if (!N) continue; + DIGlobalVariable GV(N); + if (GV.getContext().getNode() == SPNode) { + DIE *ScopedGVDie = CreateGlobalVariableDIE(ModuleCU, GV); + SPDie->AddChild(ScopedGVDie); + } + } + return SPDie; +} + +DIE *DwarfDebug::ConstructLexicalScopeDIE(DbgScope *Scope) { + unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID()); + unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID()); + + // Ignore empty scopes. + if (StartID == EndID && StartID != 0) + return NULL; + + DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block); + if (Scope->isAbstractScope()) + return ScopeDIE; + + AddLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, + StartID ? + DWLabel("label", StartID) + : DWLabel("func_begin", SubprogramCount)); + AddLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, + EndID ? + DWLabel("label", EndID) + : DWLabel("func_end", SubprogramCount)); + + + + return ScopeDIE; +} + +DIE *DwarfDebug::ConstructInlinedScopeDIE(DbgScope *Scope) { + unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID()); + unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID()); + assert (StartID && "Invalid starting label for an inlined scope!"); + assert (EndID && "Invalid end label for an inlined scope!"); + // Ignore empty scopes. + if (StartID == EndID && StartID != 0) + return NULL; + + DIScope DS(Scope->getScopeNode()); + if (DS.isNull()) + return NULL; + DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine); + + DISubprogram InlinedSP = getDISubprogram(DS.getNode()); + DIE *&OriginDIE = ModuleCU->getDieMapSlotFor(InlinedSP.getNode()); + assert (OriginDIE && "Unable to find Origin DIE!"); + AddDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin, + dwarf::DW_FORM_ref4, OriginDIE); + + AddLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, + DWLabel("label", StartID)); + AddLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, + DWLabel("label", EndID)); + + InlinedSubprogramDIEs.insert(OriginDIE); + + // Track the start label for this inlined function. + ValueMap >::iterator + I = InlineInfo.find(InlinedSP.getNode()); + + if (I == InlineInfo.end()) { + InlineInfo[InlinedSP.getNode()].push_back(std::make_pair(StartID, ScopeDIE)); + InlinedSPNodes.push_back(InlinedSP.getNode()); + } else + I->second.push_back(std::make_pair(StartID, ScopeDIE)); + + StringPool.insert(InlinedSP.getName()); + StringPool.insert(InlinedSP.getLinkageName()); + DILocation DL(Scope->getInlinedAt()); + AddUInt(ScopeDIE, dwarf::DW_AT_call_file, 0, ModuleCU->getID()); + AddUInt(ScopeDIE, dwarf::DW_AT_call_line, 0, DL.getLineNumber()); + + return ScopeDIE; +} + +DIE *DwarfDebug::ConstructVariableDIE(DbgVariable *DV, + DbgScope *Scope, CompileUnit *Unit) { + // Get the descriptor. + const DIVariable &VD = DV->getVariable(); + + // Translate tag to proper Dwarf tag. The result variable is dropped for + // now. + unsigned Tag; + switch (VD.getTag()) { + case dwarf::DW_TAG_return_variable: + return NULL; + case dwarf::DW_TAG_arg_variable: + Tag = dwarf::DW_TAG_formal_parameter; + break; + case dwarf::DW_TAG_auto_variable: // fall thru + default: + Tag = dwarf::DW_TAG_variable; + break; + } + + // Define variable debug information entry. + DIE *VariableDie = new DIE(Tag); + + + DIE *AbsDIE = NULL; + if (DbgVariable *AV = DV->getAbstractVariable()) + AbsDIE = AV->getDIE(); + + if (AbsDIE) { + DIScope DS(Scope->getScopeNode()); + DISubprogram InlinedSP = getDISubprogram(DS.getNode()); + DIE *&OriginSPDIE = ModuleCU->getDieMapSlotFor(InlinedSP.getNode()); + assert (OriginSPDIE && "Unable to find Origin DIE for the SP!"); + DIE *AbsDIE = DV->getAbstractVariable()->getDIE(); + assert (AbsDIE && "Unable to find Origin DIE for the Variable!"); + AddDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin, + dwarf::DW_FORM_ref4, AbsDIE); + } + else { + const char *Name = VD.getName(); + AddString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); + AddSourceLine(VariableDie, &VD); + + // Add variable type. + // FIXME: isBlockByrefVariable should be reformulated in terms of complex + // addresses instead. + if (VD.isBlockByrefVariable()) + AddType(Unit, VariableDie, GetBlockByrefType(VD.getType(), Name)); + else + AddType(Unit, VariableDie, VD.getType()); + } + + // Add variable address. + if (!Scope->isAbstractScope()) { + MachineLocation Location; + Location.set(RI->getFrameRegister(*MF), + RI->getFrameIndexOffset(*MF, DV->getFrameIndex())); + + + if (VD.hasComplexAddress()) + AddComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location); + else if (VD.isBlockByrefVariable()) + AddBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location); + else + AddAddress(VariableDie, dwarf::DW_AT_location, Location); + } + DV->setDIE(VariableDie); + return VariableDie; + +} +DIE *DwarfDebug::ConstructScopeDIE(DbgScope *Scope) { + if (!Scope) + return NULL; + DIScope DS(Scope->getScopeNode()); + if (DS.isNull()) + return NULL; + + DIE *ScopeDIE = NULL; + if (Scope->getInlinedAt()) + ScopeDIE = ConstructInlinedScopeDIE(Scope); + else if (DS.isSubprogram()) { + if (Scope->isAbstractScope()) + ScopeDIE = ModuleCU->getDieMapSlotFor(DS.getNode()); + else + ScopeDIE = UpdateSubprogramScopeDIE(DS.getNode()); + } + else { + ScopeDIE = ConstructLexicalScopeDIE(Scope); + if (!ScopeDIE) return NULL; + } + + // Add variables to scope. + SmallVector &Variables = Scope->getVariables(); + for (unsigned i = 0, N = Variables.size(); i < N; ++i) { + DIE *VariableDIE = ConstructVariableDIE(Variables[i], Scope, ModuleCU); + if (VariableDIE) + ScopeDIE->AddChild(VariableDIE); + } + + // Add nested scopes. + SmallVector &Scopes = Scope->getScopes(); + for (unsigned j = 0, M = Scopes.size(); j < M; ++j) { + // Define the Scope debug information entry. + DIE *NestedDIE = ConstructScopeDIE(Scopes[j]); + if (NestedDIE) + ScopeDIE->AddChild(NestedDIE); + } + return ScopeDIE; +} + /// ConstructDbgScope - Construct the components of a scope. -/// +/// FIXME: Remove void DwarfDebug::ConstructDbgScope(DbgScope *ParentScope, unsigned ParentStartID, unsigned ParentEndID, @@ -1408,34 +1654,6 @@ if (VariableDie) ParentDie->AddChild(VariableDie); } - // Add concrete instances to scope. - SmallVector &ConcreteInsts = - ParentScope->getConcreteInsts(); - for (unsigned i = 0, N = ConcreteInsts.size(); i < N; ++i) { - DbgConcreteScope *ConcreteInst = ConcreteInsts[i]; - DIE *Die = ConcreteInst->getDie(); - - unsigned StartID = ConcreteInst->getStartLabelID(); - unsigned EndID = ConcreteInst->getEndLabelID(); - - // Add the scope bounds. - if (StartID) - AddLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, - DWLabel("label", StartID)); - else - AddLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, - DWLabel("func_begin", SubprogramCount)); - - if (EndID) - AddLabel(Die, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, - DWLabel("label", EndID)); - else - AddLabel(Die, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, - DWLabel("func_end", SubprogramCount)); - - ParentDie->AddChild(Die); - } - // Add nested scopes. SmallVector &Scopes = ParentScope->getScopes(); for (unsigned j = 0, M = Scopes.size(); j < M; ++j) { @@ -1450,8 +1668,7 @@ // Do not ignore inlined scopes even if they don't have any variables or // scopes. - if (Scope->getScopes().empty() && Scope->getVariables().empty() && - Scope->getConcreteInsts().empty()) + if (Scope->getScopes().empty() && Scope->getVariables().empty()) continue; if (StartID == ParentStartID && EndID == ParentEndID) { @@ -1482,9 +1699,9 @@ } } -/// ConstructFunctionDbgScope - Construct the scope for the subprogram. -/// -void DwarfDebug::ConstructFunctionDbgScope(DbgScope *RootScope, +/// ConstructCurrentFnDbgScope - Construct the scope for the subprogram. +/// FIXME: Remove +void DwarfDebug::ConstructCurrentFnDbgScope(DbgScope *RootScope, bool AbstractScope) { // Exit if there is no root scope. if (!RootScope) return; @@ -1529,7 +1746,7 @@ } /// ConstructDefaultDbgScope - Construct a default scope for the subprogram. -/// +/// FIXME: Remove void DwarfDebug::ConstructDefaultDbgScope(MachineFunction *MF) { StringMap &Globals = ModuleCU->getGlobals(); StringMap::iterator GI = Globals.find(MF->getFunction()->getName()); @@ -1715,7 +1932,7 @@ ConstructGlobalVariableDIE(*I); } - // Create DIEs for each of the externally visible subprograms. + // Create DIEs for each subprogram. for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(), E = DbgFinder.subprogram_end(); I != E; ++I) ConstructSubprogram(*I); @@ -1759,6 +1976,13 @@ if (TimePassesIsEnabled) DebugTimer->startTimer(); + // Attach DW_AT_inline attribute with inlined subprogram DIEs. + for (SmallPtrSet::iterator AI = InlinedSubprogramDIEs.begin(), + AE = InlinedSubprogramDIEs.end(); AI != AE; ++AI) { + DIE *ISP = *AI; + AddUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined); + } + // Standard sections final addresses. Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection()); EmitLabel("text_end", 0); @@ -1816,55 +2040,98 @@ DebugTimer->stopTimer(); } +/// findAbstractVariable - Find abstract variable, if any, associated with Var. +DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var, unsigned FrameIdx, + DILocation &ScopeLoc) { + + DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var.getNode()); + if (AbsDbgVariable) + return AbsDbgVariable; + + DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope().getNode()); + if (!Scope) + return NULL; + + AbsDbgVariable = new DbgVariable(Var, FrameIdx); + Scope->AddVariable(AbsDbgVariable); + AbstractVariables[Var.getNode()] = AbsDbgVariable; + return AbsDbgVariable; +} + /// CollectVariableInfo - Populate DbgScope entries with variables' info. void DwarfDebug::CollectVariableInfo() { if (!MMI) return; + MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo(); for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(), VE = VMap.end(); VI != VE; ++VI) { MetadataBase *MB = VI->first; MDNode *Var = dyn_cast_or_null(MB); + if (!Var) continue; DIVariable DV (Var); - if (DV.isNull()) continue; - unsigned VSlot = VI->second; - DbgScope *Scope = NULL; - ValueMap::iterator DSI = - DbgScopeMap.find(DV.getContext().getNode()); - if (DSI != DbgScopeMap.end()) - Scope = DSI->second; - else - // There is not any instruction assocated with this scope, so get - // a new scope. - Scope = getDbgScope(DV.getContext().getNode(), - NULL /* Not an instruction */, - NULL /* Not inlined */); + std::pair< unsigned, MDNode *> VP = VI->second; + DILocation ScopeLoc(VP.second); + + DbgScope *Scope = + ConcreteScopes.lookup(ScopeLoc.getOrigLocation().getNode()); + if (!Scope) + Scope = DbgScopeMap.lookup(ScopeLoc.getScope().getNode()); assert (Scope && "Unable to find variable scope!"); - Scope->AddVariable(new DbgVariable(DV, VSlot, false)); + + DbgVariable *RegVar = new DbgVariable(DV, VP.first); + Scope->AddVariable(RegVar); + if (DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.first, ScopeLoc)) + RegVar->setAbstractVariable(AbsDbgVariable); } } -/// SetDbgScopeBeginLabels - Update DbgScope begin labels for the scopes that -/// start with this machine instruction. -void DwarfDebug::SetDbgScopeBeginLabels(const MachineInstr *MI, unsigned Label) { +/// BeginScope - Process beginning of a scope starting at Label. +void DwarfDebug::BeginScope(const MachineInstr *MI, unsigned Label) { InsnToDbgScopeMapTy::iterator I = DbgScopeBeginMap.find(MI); if (I == DbgScopeBeginMap.end()) return; - SmallVector &SD = I->second; - for (SmallVector::iterator SDI = SD.begin(), SDE = SD.end(); + ScopeVector &SD = DbgScopeBeginMap[MI]; + for (ScopeVector::iterator SDI = SD.begin(), SDE = SD.end(); SDI != SDE; ++SDI) (*SDI)->setStartLabelID(Label); } -/// SetDbgScopeEndLabels - Update DbgScope end labels for the scopes that -/// end with this machine instruction. -void DwarfDebug::SetDbgScopeEndLabels(const MachineInstr *MI, unsigned Label) { +/// EndScope - Process end of a scope. +void DwarfDebug::EndScope(const MachineInstr *MI) { InsnToDbgScopeMapTy::iterator I = DbgScopeEndMap.find(MI); if (I == DbgScopeEndMap.end()) return; + + unsigned Label = MMI->NextLabelID(); + Asm->printLabel(Label); + SmallVector &SD = I->second; for (SmallVector::iterator SDI = SD.begin(), SDE = SD.end(); SDI != SDE; ++SDI) (*SDI)->setEndLabelID(Label); + return; +} + +/// createDbgScope - Create DbgScope for the scope. +void DwarfDebug::createDbgScope(MDNode *Scope, MDNode *InlinedAt) { + + if (!InlinedAt) { + DbgScope *WScope = DbgScopeMap.lookup(Scope); + if (WScope) + return; + WScope = new DbgScope(NULL, DIDescriptor(Scope), NULL); + DbgScopeMap.insert(std::make_pair(Scope, WScope)); + return; + } + + DbgScope *WScope = DbgScopeMap.lookup(InlinedAt); + if (WScope) + return; + + WScope = new DbgScope(NULL, DIDescriptor(Scope), InlinedAt); + DbgScopeMap.insert(std::make_pair(InlinedAt, WScope)); + DILocation DL(InlinedAt); + createDbgScope(DL.getScope().getNode(), DL.getOrigLocation().getNode()); } /// ExtractScopeInformation - Scan machine instructions in this function @@ -1875,26 +2142,41 @@ if (!DbgScopeMap.empty()) return false; - // Scan each instruction and create scopes. + // Scan each instruction and create scopes. First build working set of scopes. for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E; ++I) { for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); II != IE; ++II) { const MachineInstr *MInsn = II; DebugLoc DL = MInsn->getDebugLoc(); - if (DL.isUnknown()) - continue; + if (DL.isUnknown()) continue; DebugLocTuple DLT = MF->getDebugLocTuple(DL); - if (!DLT.Scope) - continue; + if (!DLT.Scope) continue; // There is no need to create another DIE for compile unit. For all // other scopes, create one DbgScope now. This will be translated // into a scope DIE at the end. - DIDescriptor D(DLT.Scope); - if (!D.isCompileUnit()) { - DbgScope *Scope = getDbgScope(DLT.Scope, MInsn, DLT.InlinedAtLoc); - Scope->setLastInsn(MInsn); - } + if (DIDescriptor(DLT.Scope).isCompileUnit()) continue; + createDbgScope(DLT.Scope, DLT.InlinedAtLoc); + } + } + + + // Build scope hierarchy using working set of scopes. + for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); + I != E; ++I) { + for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); + II != IE; ++II) { + const MachineInstr *MInsn = II; + DebugLoc DL = MInsn->getDebugLoc(); + if (DL.isUnknown()) continue; + DebugLocTuple DLT = MF->getDebugLocTuple(DL); + if (!DLT.Scope) continue; + // There is no need to create another DIE for compile unit. For all + // other scopes, create one DbgScope now. This will be translated + // into a scope DIE at the end. + if (DIDescriptor(DLT.Scope).isCompileUnit()) continue; + DbgScope *Scope = getUpdatedDbgScope(DLT.Scope, MInsn, DLT.InlinedAtLoc); + Scope->setLastInsn(MInsn); } } @@ -1902,8 +2184,8 @@ // last instruction as this scope's last instrunction. for (ValueMap::iterator DI = DbgScopeMap.begin(), DE = DbgScopeMap.end(); DI != DE; ++DI) { - DbgScope *S = DI->second; - if (!S) continue; + if (DI->second->isAbstractScope()) + continue; assert (DI->second->getFirstInsn() && "Invalid first instruction!"); DI->second->FixInstructionMarkers(); assert (DI->second->getLastInsn() && "Invalid last instruction!"); @@ -1916,7 +2198,8 @@ for (ValueMap::iterator DI = DbgScopeMap.begin(), DE = DbgScopeMap.end(); DI != DE; ++DI) { DbgScope *S = DI->second; - if (!S) continue; + if (S->isAbstractScope()) + continue; const MachineInstr *MI = S->getFirstInsn(); assert (MI && "DbgScope does not have first instruction!"); @@ -1924,8 +2207,7 @@ if (IDI != DbgScopeBeginMap.end()) IDI->second.push_back(S); else - DbgScopeBeginMap.insert(std::make_pair(MI, - SmallVector(2, S))); + DbgScopeBeginMap[MI].push_back(S); MI = S->getLastInsn(); assert (MI && "DbgScope does not have last instruction!"); @@ -1933,31 +2215,12 @@ if (IDI != DbgScopeEndMap.end()) IDI->second.push_back(S); else - DbgScopeEndMap.insert(std::make_pair(MI, - SmallVector(2, S))); + DbgScopeEndMap[MI].push_back(S); } return !DbgScopeMap.empty(); } -static DISubprogram getDISubprogram(MDNode *N) { - - DIDescriptor D(N); - if (D.isNull()) - return DISubprogram(); - - if (D.isCompileUnit()) - return DISubprogram(); - - if (D.isSubprogram()) - return DISubprogram(N); - - if (D.isLexicalBlock()) - return getDISubprogram(DILexicalBlock(N).getContext().getNode()); - - llvm_unreachable("Unexpected Descriptor!"); -} - /// BeginFunction - Gather pre-function debug information. Assumes being /// emitted immediately after the function entry point. void DwarfDebug::BeginFunction(MachineFunction *MF) { @@ -2034,15 +2297,10 @@ Lines.begin(), Lines.end()); } - // Construct the DbgScope for abstract instances. - for (SmallVector::iterator - I = AbstractInstanceRootList.begin(), - E = AbstractInstanceRootList.end(); I != E; ++I) - ConstructFunctionDbgScope(*I); - +#ifndef ATTACH_DEBUG_INFO_TO_AN_INSN // Construct scopes for subprogram. - if (FunctionDbgScope) - ConstructFunctionDbgScope(FunctionDbgScope); + if (CurrentFnDbgScope) + ConstructCurrentFnDbgScope(CurrentFnDbgScope); else // FIXME: This is wrong. We are essentially getting past a problem with // debug information not being able to handle unreachable blocks that have @@ -2053,22 +2311,25 @@ // desirable. And a better way of handling this (and all of the debugging // information) needs to be explored. ConstructDefaultDbgScope(MF); +#else + // Construct abstract scopes. + for (SmallVector::iterator AI = AbstractScopesList.begin(), + AE = AbstractScopesList.end(); AI != AE; ++AI) + ConstructScopeDIE(*AI); + ConstructScopeDIE(CurrentFnDbgScope); +#endif DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount, MMI->getFrameMoves())); // Clear debug info - if (FunctionDbgScope) { - delete FunctionDbgScope; + if (CurrentFnDbgScope) { + CurrentFnDbgScope = NULL; DbgScopeMap.clear(); DbgScopeBeginMap.clear(); DbgScopeEndMap.clear(); - DbgAbstractScopeMap.clear(); - DbgConcreteScopeMap.clear(); - FunctionDbgScope = NULL; - LexicalScopeStack.clear(); - AbstractInstanceRootList.clear(); - AbstractInstanceRootMap.clear(); + ConcreteScopes.clear(); + AbstractScopesList.clear(); } Lines.clear(); @@ -2143,7 +2404,6 @@ DbgScope *Scope = getOrCreateScope(N); unsigned ID = MMI->NextLabelID(); if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID); - LexicalScopeStack.push_back(Scope); if (TimePassesIsEnabled) DebugTimer->stopTimer(); @@ -2159,12 +2419,6 @@ DbgScope *Scope = getOrCreateScope(N); unsigned ID = MMI->NextLabelID(); Scope->setEndLabelID(ID); - // FIXME : region.end() may not be in the last basic block. - // For now, do not pop last lexical scope because next basic - // block may start new inlined function's body. - unsigned LSSize = LexicalScopeStack.size(); - if (LSSize != 0 && LSSize != 1) - LexicalScopeStack.pop_back(); if (TimePassesIsEnabled) DebugTimer->stopTimer(); @@ -2179,157 +2433,22 @@ DIDescriptor Desc(N); DbgScope *Scope = NULL; - bool InlinedFnVar = false; if (Desc.getTag() == dwarf::DW_TAG_variable) Scope = getOrCreateScope(DIGlobalVariable(N).getContext().getNode()); else { - bool InlinedVar = false; MDNode *Context = DIVariable(N).getContext().getNode(); - DISubprogram SP(Context); - if (!SP.isNull()) { - // SP is inserted into DbgAbstractScopeMap when inlined function - // start was recorded by RecordInlineFnStart. - ValueMap::iterator - I = DbgAbstractScopeMap.find(SP.getNode()); - if (I != DbgAbstractScopeMap.end()) { - InlinedVar = true; - Scope = I->second; - } - } - if (!InlinedVar) - Scope = getOrCreateScope(Context); + Scope = getOrCreateScope(Context); } assert(Scope && "Unable to find the variable's scope"); - DbgVariable *DV = new DbgVariable(DIVariable(N), FrameIndex, InlinedFnVar); + DbgVariable *DV = new DbgVariable(DIVariable(N), FrameIndex); Scope->AddVariable(DV); if (TimePassesIsEnabled) DebugTimer->stopTimer(); } -//// RecordInlinedFnStart - Indicate the start of inlined subroutine. -unsigned DwarfDebug::RecordInlinedFnStart(DISubprogram &SP, DICompileUnit CU, - unsigned Line, unsigned Col) { - unsigned LabelID = MMI->NextLabelID(); - - if (!MAI->doesDwarfUsesInlineInfoSection()) - return LabelID; - - if (TimePassesIsEnabled) - DebugTimer->startTimer(); - - MDNode *Node = SP.getNode(); - DenseMap::iterator - II = AbstractInstanceRootMap.find(Node); - - if (II == AbstractInstanceRootMap.end()) { - // Create an abstract instance entry for this inlined function if it doesn't - // already exist. - DbgScope *Scope = new DbgScope(NULL, DIDescriptor(Node)); - - // Get the compile unit context. - DIE *SPDie = ModuleCU->getDieMapSlotFor(Node); - if (!SPDie) - SPDie = CreateSubprogramDIE(ModuleCU, SP, false, true); - - // Mark as being inlined. This makes this subprogram entry an abstract - // instance root. - // FIXME: Our debugger doesn't care about the value of DW_AT_inline, only - // that it's defined. That probably won't change in the future. However, - // this could be more elegant. - AddUInt(SPDie, dwarf::DW_AT_inline, 0, dwarf::DW_INL_declared_not_inlined); - - // Keep track of the abstract scope for this function. - DbgAbstractScopeMap[Node] = Scope; - - AbstractInstanceRootMap[Node] = Scope; - AbstractInstanceRootList.push_back(Scope); - } - - // Create a concrete inlined instance for this inlined function. - DbgConcreteScope *ConcreteScope = new DbgConcreteScope(DIDescriptor(Node)); - DIE *ScopeDie = new DIE(dwarf::DW_TAG_inlined_subroutine); - ScopeDie->setAbstractCompileUnit(ModuleCU); - - DIE *Origin = ModuleCU->getDieMapSlotFor(Node); - AddDIEEntry(ScopeDie, dwarf::DW_AT_abstract_origin, - dwarf::DW_FORM_ref4, Origin); - AddUInt(ScopeDie, dwarf::DW_AT_call_file, 0, ModuleCU->getID()); - AddUInt(ScopeDie, dwarf::DW_AT_call_line, 0, Line); - AddUInt(ScopeDie, dwarf::DW_AT_call_column, 0, Col); - - ConcreteScope->setDie(ScopeDie); - ConcreteScope->setStartLabelID(LabelID); - MMI->RecordUsedDbgLabel(LabelID); - - LexicalScopeStack.back()->AddConcreteInst(ConcreteScope); - - // Keep track of the concrete scope that's inlined into this function. - ValueMap >::iterator - SI = DbgConcreteScopeMap.find(Node); - - if (SI == DbgConcreteScopeMap.end()) - DbgConcreteScopeMap[Node].push_back(ConcreteScope); - else - SI->second.push_back(ConcreteScope); - - // Track the start label for this inlined function. - ValueMap >::iterator - I = InlineInfo.find(Node); - - if (I == InlineInfo.end()) - InlineInfo[Node].push_back(LabelID); - else - I->second.push_back(LabelID); - - if (TimePassesIsEnabled) - DebugTimer->stopTimer(); - - return LabelID; -} - -/// RecordInlinedFnEnd - Indicate the end of inlined subroutine. -unsigned DwarfDebug::RecordInlinedFnEnd(DISubprogram &SP) { - if (!MAI->doesDwarfUsesInlineInfoSection()) - return 0; - - if (TimePassesIsEnabled) - DebugTimer->startTimer(); - - MDNode *Node = SP.getNode(); - ValueMap >::iterator - I = DbgConcreteScopeMap.find(Node); - - if (I == DbgConcreteScopeMap.end()) { - // FIXME: Can this situation actually happen? And if so, should it? - if (TimePassesIsEnabled) - DebugTimer->stopTimer(); - - return 0; - } - - SmallVector &Scopes = I->second; - if (Scopes.empty()) { - // Returned ID is 0 if this is unbalanced "end of inlined - // scope". This could happen if optimizer eats dbg intrinsics - // or "beginning of inlined scope" is not recoginized due to - // missing location info. In such cases, ignore this region.end. - return 0; - } - - DbgScope *Scope = Scopes.back(); Scopes.pop_back(); - unsigned ID = MMI->NextLabelID(); - MMI->RecordUsedDbgLabel(ID); - Scope->setEndLabelID(ID); - - if (TimePassesIsEnabled) - DebugTimer->stopTimer(); - - return ID; -} - //===----------------------------------------------------------------------===// // Emit Methods //===----------------------------------------------------------------------===// @@ -2475,10 +2594,7 @@ case dwarf::DW_AT_abstract_origin: { DIEEntry *E = cast(Values[i]); DIE *Origin = E->getEntry(); - unsigned Addr = - CompileUnitOffsets[Die->getAbstractCompileUnit()] + - Origin->getOffset(); - + unsigned Addr = Origin->getOffset(); Asm->EmitInt32(Addr); break; } @@ -3007,10 +3123,14 @@ Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("Dwarf Version"); Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)"); - for (ValueMap >::iterator - I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) { - MDNode *Node = I->first; - SmallVector &Labels = I->second; + for (SmallVector::iterator I = InlinedSPNodes.begin(), + E = InlinedSPNodes.end(); I != E; ++I) { + +// for (ValueMap >::iterator + // I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) { + MDNode *Node = *I; + ValueMap >::iterator II = InlineInfo.find(Node); + SmallVector &Labels = II->second; DISubprogram SP(Node); const char *LName = SP.getLinkageName(); const char *Name = SP.getName(); @@ -3024,17 +3144,21 @@ // __asm__ attribute. if (LName[0] == 1) LName = &LName[1]; - Asm->EmitString(LName); +// Asm->EmitString(LName); + EmitSectionOffset("string", "section_str", + StringPool.idFor(LName), false, true); + } Asm->EOL("MIPS linkage name"); - - Asm->EmitString(Name); Asm->EOL("Function name"); - +// Asm->EmitString(Name); + EmitSectionOffset("string", "section_str", + StringPool.idFor(Name), false, true); + Asm->EOL("Function name"); Asm->EmitULEB128Bytes(Labels.size()); Asm->EOL("Inline count"); - for (SmallVector::iterator LI = Labels.begin(), + for (SmallVector::iterator LI = Labels.begin(), LE = Labels.end(); LI != LE; ++LI) { - DIE *SP = ModuleCU->getDieMapSlotFor(Node); + DIE *SP = LI->second; Asm->EmitInt32(SP->getOffset()); Asm->EOL("DIE offset"); if (TD->getPointerSize() == sizeof(int32_t)) @@ -3042,7 +3166,7 @@ else O << MAI->getData64bitsDirective(); - PrintLabelName("label", *LI); Asm->EOL("low_pc"); + PrintLabelName("label", LI->first); Asm->EOL("low_pc"); } } Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue Nov 10 17:06:00 2009 @@ -134,52 +134,52 @@ /// bool shouldEmit; - // FunctionDbgScope - Top level scope for the current function. + // CurrentFnDbgScope - Top level scope for the current function. // - DbgScope *FunctionDbgScope; + DbgScope *CurrentFnDbgScope; /// DbgScopeMap - Tracks the scopes in the current function. + /// ValueMap DbgScopeMap; + /// ConcreteScopes - Tracks the concrete scopees in the current function. + /// These scopes are also included in DbgScopeMap. + ValueMap ConcreteScopes; + + /// AbstractScopes - Tracks the abstract scopes a module. These scopes are + /// not included DbgScopeMap. + ValueMap AbstractScopes; + SmallVectorAbstractScopesList; + + /// AbstractVariables - Collection on abstract variables. + ValueMap AbstractVariables; + + /// InliendSubprogramDIEs - Collection of subprgram DIEs that are marked + /// (at the end of the module) as DW_AT_inline. + SmallPtrSet InlinedSubprogramDIEs; + + /// AbstractSubprogramDIEs - Collection of abstruct subprogram DIEs. + SmallPtrSet AbstractSubprogramDIEs; + /// ScopedGVs - Tracks global variables that are not at file scope. /// For example void f() { static int b = 42; } SmallVector ScopedGVs; - typedef DenseMap > + typedef SmallVector ScopeVector; + typedef DenseMap InsnToDbgScopeMapTy; - /// DbgScopeBeginMap - Maps instruction with a list DbgScopes it starts. + /// DbgScopeBeginMap - Maps instruction with a list of DbgScopes it starts. InsnToDbgScopeMapTy DbgScopeBeginMap; /// DbgScopeEndMap - Maps instruction with a list DbgScopes it ends. InsnToDbgScopeMapTy DbgScopeEndMap; - /// DbgAbstractScopeMap - Tracks abstract instance scopes in the current - /// function. - ValueMap DbgAbstractScopeMap; - - /// DbgConcreteScopeMap - Tracks concrete instance scopes in the current - /// function. - ValueMap > DbgConcreteScopeMap; - /// InlineInfo - Keep track of inlined functions and their location. This /// information is used to populate debug_inlined section. - ValueMap > InlineInfo; - - /// AbstractInstanceRootMap - Map of abstract instance roots of inlined - /// functions. These are subroutine entries that contain a DW_AT_inline - /// attribute. - DenseMap AbstractInstanceRootMap; - - /// AbstractInstanceRootList - List of abstract instance roots of inlined - /// functions. These are subroutine entries that contain a DW_AT_inline - /// attribute. - SmallVector AbstractInstanceRootList; - - /// LexicalScopeStack - A stack of lexical scopes. The top one is the current - /// scope. - SmallVector LexicalScopeStack; + typedef std::pair InlineInfoLabels; + ValueMap > InlineInfo; + SmallVector InlinedSPNodes; /// CompileUnitOffsets - A vector of the offsets of the compile units. This is /// used when calculating the "origin" of a concrete instance of an inlined @@ -361,10 +361,24 @@ /// DIE *CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit); - /// getDbgScope - Returns the scope associated with the given descriptor. - /// + /// getUpdatedDbgScope - Find or create DbgScope assicated with + /// the instruction. Initialize scope and update scope hierarchy. + DbgScope *getUpdatedDbgScope(MDNode *N, const MachineInstr *MI, MDNode *InlinedAt); + + /// createDbgScope - Create DbgScope for the scope. + void createDbgScope(MDNode *Scope, MDNode *InlinedAt); DbgScope *getOrCreateScope(MDNode *N); - DbgScope *getDbgScope(MDNode *N, const MachineInstr *MI, MDNode *InlinedAt); + DbgScope *getOrCreateAbstractScope(MDNode *N); + + /// findAbstractVariable - Find abstract variable associated with Var. + DbgVariable *findAbstractVariable(DIVariable &Var, unsigned FrameIdx, + DILocation &Loc); + + DIE *UpdateSubprogramScopeDIE(MDNode *SPNode); + DIE *ConstructLexicalScopeDIE(DbgScope *Scope); + DIE *ConstructScopeDIE(DbgScope *Scope); + DIE *ConstructInlinedScopeDIE(DbgScope *Scope); + DIE *ConstructVariableDIE(DbgVariable *DV, DbgScope *S, CompileUnit *Unit); /// ConstructDbgScope - Construct the components of a scope. /// @@ -372,10 +386,10 @@ unsigned ParentStartID, unsigned ParentEndID, DIE *ParentDie, CompileUnit *Unit); - /// ConstructFunctionDbgScope - Construct the scope for the subprogram. + /// ConstructCurrentFnDbgScope - Construct the scope for the subprogram. /// - void ConstructFunctionDbgScope(DbgScope *RootScope, - bool AbstractScope = false); + void ConstructCurrentFnDbgScope(DbgScope *RootScope, + bool AbstractScope = false); /// ConstructDefaultDbgScope - Construct a default scope for the subprogram. /// @@ -544,13 +558,6 @@ /// RecordVariable - Indicate the declaration of a local variable. void RecordVariable(MDNode *N, unsigned FrameIndex); - //// RecordInlinedFnStart - Indicate the start of inlined subroutine. - unsigned RecordInlinedFnStart(DISubprogram &SP, DICompileUnit CU, - unsigned Line, unsigned Col); - - /// RecordInlinedFnEnd - Indicate the end of inlined subroutine. - unsigned RecordInlinedFnEnd(DISubprogram &SP); - /// ExtractScopeInformation - Scan machine instructions in this function /// and collect DbgScopes. Return true, if atleast one scope was found. bool ExtractScopeInformation(MachineFunction *MF); @@ -558,15 +565,16 @@ /// CollectVariableInfo - Populate DbgScope entries with variables' info. void CollectVariableInfo(); - /// SetDbgScopeBeginLabels - Update DbgScope begin labels for the scopes that - /// start with this machine instruction. - void SetDbgScopeBeginLabels(const MachineInstr *MI, unsigned Label); - /// SetDbgScopeEndLabels - Update DbgScope end labels for the scopes that /// end with this machine instruction. void SetDbgScopeEndLabels(const MachineInstr *MI, unsigned Label); -}; + /// BeginScope - Process beginning of a scope starting at Label. + void BeginScope(const MachineInstr *MI, unsigned Label); + + /// EndScope - Prcess end of a scope. + void EndScope(const MachineInstr *MI); +}; } // End of namespace llvm #endif Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Tue Nov 10 17:06:00 2009 @@ -108,20 +108,9 @@ return DD && DD->ShouldEmitDwarfDebug(); } -//// RecordInlinedFnStart -unsigned DwarfWriter::RecordInlinedFnStart(DISubprogram SP, DICompileUnit CU, - unsigned Line, unsigned Col) { - return DD->RecordInlinedFnStart(SP, CU, Line, Col); +void DwarfWriter::BeginScope(const MachineInstr *MI, unsigned L) { + DD->BeginScope(MI, L); } - -/// RecordInlinedFnEnd - Indicate the end of inlined subroutine. -unsigned DwarfWriter::RecordInlinedFnEnd(DISubprogram SP) { - return DD->RecordInlinedFnEnd(SP); -} - -void DwarfWriter::SetDbgScopeBeginLabels(const MachineInstr *MI, unsigned L) { - DD->SetDbgScopeEndLabels(MI, L); -} -void DwarfWriter::SetDbgScopeEndLabels(const MachineInstr *MI, unsigned L) { - DD->SetDbgScopeBeginLabels(MI, L); +void DwarfWriter::EndScope(const MachineInstr *MI) { + DD->EndScope(MI); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Tue Nov 10 17:06:00 2009 @@ -43,6 +43,7 @@ #include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" +#include "llvm/LLVMContext.h" #include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" @@ -347,21 +348,9 @@ && DW->ShouldEmitDwarfDebug()) { unsigned ID = 0; DISubprogram Subprogram(REI->getContext()); - if (isInlinedFnEnd(*REI, MF.getFunction())) { - // This is end of an inlined function. - const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); - ID = DW->RecordInlinedFnEnd(Subprogram); - if (ID) - // Returned ID is 0 if this is unbalanced "end of inlined - // scope". This could happen if optimizer eats dbg intrinsics - // or "beginning of inlined scope" is not recoginized due to - // missing location info. In such cases, ignore this region.end. - BuildMI(MBB, DL, II).addImm(ID); - } else { - const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); - ID = DW->RecordRegionEnd(REI->getContext()); - BuildMI(MBB, DL, II).addImm(ID); - } + const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); + ID = DW->RecordRegionEnd(REI->getContext()); + BuildMI(MBB, DL, II).addImm(ID); } return true; } @@ -371,28 +360,6 @@ || !DW->ShouldEmitDwarfDebug()) return true; - if (isInlinedFnStart(*FSI, MF.getFunction())) { - // This is a beginning of an inlined function. - - // If llvm.dbg.func.start is seen in a new block before any - // llvm.dbg.stoppoint intrinsic then the location info is unknown. - // FIXME : Why DebugLoc is reset at the beginning of each block ? - DebugLoc PrevLoc = DL; - if (PrevLoc.isUnknown()) - return true; - // Record the source line. - setCurDebugLoc(ExtractDebugLocation(*FSI, MF.getDebugLocInfo())); - - DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); - DISubprogram SP(FSI->getSubprogram()); - unsigned LabelID = - DW->RecordInlinedFnStart(SP,DICompileUnit(PrevLocTpl.Scope), - PrevLocTpl.Line, PrevLocTpl.Col); - const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); - BuildMI(MBB, DL, II).addImm(LabelID); - return true; - } - // This is a beginning of a new function. MF.setDefaultDebugLoc(ExtractDebugLocation(*FSI, MF.getDebugLocInfo())); @@ -416,8 +383,13 @@ StaticAllocaMap.find(AI); if (SI == StaticAllocaMap.end()) break; // VLAs. int FI = SI->second; - if (MMI) - MMI->setVariableDbgInfo(DI->getVariable(), FI); + if (MMI) { + MetadataContext &TheMetadata = + DI->getParent()->getContext().getMetadata(); + unsigned MDDbgKind = TheMetadata.getMDKind("dbg"); + MDNode *Dbg = TheMetadata.getMD(MDDbgKind, DI); + MMI->setVariableDbgInfo(DI->getVariable(), FI, Dbg); + } #ifndef ATTACH_DEBUG_INFO_TO_AN_INSN DW->RecordVariable(DI->getVariable(), FI); #endif Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Tue Nov 10 17:06:00 2009 @@ -26,6 +26,7 @@ #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" +#include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/GCStrategy.h" @@ -3931,25 +3932,8 @@ || !DW->ShouldEmitDwarfDebug()) return 0; - MachineFunction &MF = DAG.getMachineFunction(); DISubprogram Subprogram(REI.getContext()); - if (isInlinedFnEnd(REI, MF.getFunction())) { - // This is end of inlined function. Debugging information for inlined - // function is not handled yet (only supported by FastISel). - if (OptLevel == CodeGenOpt::None) { - unsigned ID = DW->RecordInlinedFnEnd(Subprogram); - if (ID != 0) - // Returned ID is 0 if this is unbalanced "end of inlined - // scope". This could happen if optimizer eats dbg intrinsics or - // "beginning of inlined scope" is not recoginized due to missing - // location info. In such cases, do ignore this region.end. - DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), - getRoot(), ID)); - } - return 0; - } - unsigned LabelID = DW->RecordRegionEnd(REI.getContext()); DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), @@ -3963,37 +3947,6 @@ return 0; MachineFunction &MF = DAG.getMachineFunction(); - // This is a beginning of an inlined function. - if (isInlinedFnStart(FSI, MF.getFunction())) { - if (OptLevel != CodeGenOpt::None) - // FIXME: Debugging informaation for inlined function is only - // supported at CodeGenOpt::Node. - return 0; - - DebugLoc PrevLoc = CurDebugLoc; - // If llvm.dbg.func.start is seen in a new block before any - // llvm.dbg.stoppoint intrinsic then the location info is unknown. - // FIXME : Why DebugLoc is reset at the beginning of each block ? - if (PrevLoc.isUnknown()) - return 0; - - // Record the source line. - setCurDebugLoc(ExtractDebugLocation(FSI, MF.getDebugLocInfo())); - - if (!DW || !DW->ShouldEmitDwarfDebug()) - return 0; - DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); - DISubprogram SP(FSI.getSubprogram()); - DICompileUnit CU(PrevLocTpl.Scope); - unsigned LabelID = DW->RecordInlinedFnStart(SP, CU, - PrevLocTpl.Line, - PrevLocTpl.Col); - DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), - getRoot(), LabelID)); - return 0; - } - - // This is a beginning of a new function. MF.setDefaultDebugLoc(ExtractDebugLocation(FSI, MF.getDebugLocInfo())); if (!DW || !DW->ShouldEmitDwarfDebug()) @@ -4028,8 +3981,13 @@ int FI = SI->second; #ifdef ATTACH_DEBUG_INFO_TO_AN_INSN MachineModuleInfo *MMI = DAG.getMachineModuleInfo(); - if (MMI) - MMI->setVariableDbgInfo(Variable, FI); + if (MMI) { + MetadataContext &TheMetadata = + DI.getParent()->getContext().getMetadata(); + unsigned MDDbgKind = TheMetadata.getMDKind("dbg"); + MDNode *Dbg = TheMetadata.getMD(MDDbgKind, &DI); + MMI->setVariableDbgInfo(Variable, FI, Dbg); + } #else DW->RecordVariable(Variable, FI); #endif Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Nov 10 17:06:00 2009 @@ -387,13 +387,14 @@ if (MDDbgKind) { // Update DebugLoc if debug information is attached with this // instruction. - if (MDNode *Dbg = TheMetadata.getMD(MDDbgKind, I)) { - DILocation DILoc(Dbg); - DebugLoc Loc = ExtractDebugLocation(DILoc, MF->getDebugLocInfo()); - SDL->setCurDebugLoc(Loc); - if (MF->getDefaultDebugLoc().isUnknown()) - MF->setDefaultDebugLoc(Loc); - } + if (!isa(I)) + if (MDNode *Dbg = TheMetadata.getMD(MDDbgKind, I)) { + DILocation DILoc(Dbg); + DebugLoc Loc = ExtractDebugLocation(DILoc, MF->getDebugLocInfo()); + SDL->setCurDebugLoc(Loc); + if (MF->getDefaultDebugLoc().isUnknown()) + MF->setDefaultDebugLoc(Loc); + } } if (!isa(I)) SDL->visit(*I); @@ -750,14 +751,15 @@ if (MDDbgKind) { // Update DebugLoc if debug information is attached with this // instruction. - if (MDNode *Dbg = TheMetadata.getMD(MDDbgKind, BI)) { - DILocation DILoc(Dbg); - DebugLoc Loc = ExtractDebugLocation(DILoc, - MF.getDebugLocInfo()); - FastIS->setCurDebugLoc(Loc); - if (MF.getDefaultDebugLoc().isUnknown()) - MF.setDefaultDebugLoc(Loc); - } + if (!isa(BI)) + if (MDNode *Dbg = TheMetadata.getMD(MDDbgKind, BI)) { + DILocation DILoc(Dbg); + DebugLoc Loc = ExtractDebugLocation(DILoc, + MF.getDebugLocInfo()); + FastIS->setCurDebugLoc(Loc); + if (MF.getDefaultDebugLoc().isUnknown()) + MF.setDefaultDebugLoc(Loc); + } } // Just before the terminator instruction, insert instructions to Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Tue Nov 10 17:06:00 2009 @@ -20,6 +20,7 @@ #include "llvm/IntrinsicInst.h" #include "llvm/GlobalVariable.h" #include "llvm/Function.h" +#include "llvm/LLVMContext.h" #include "llvm/Support/CFG.h" #include "llvm/Transforms/Utils/ValueMapper.h" #include "llvm/Analysis/ConstantFolding.h" @@ -346,6 +347,27 @@ Ops.size(), TD); } +static MDNode *UpdateInlinedAtInfo(MDNode *InsnMD, MDNode *TheCallMD, + LLVMContext &Context) { + DILocation ILoc(InsnMD); + if (ILoc.isNull()) return InsnMD; + + DILocation CallLoc(TheCallMD); + if (CallLoc.isNull()) return InsnMD; + + DILocation OrigLocation = ILoc.getOrigLocation(); + MDNode *NewLoc = TheCallMD; + if (!OrigLocation.isNull()) + NewLoc = UpdateInlinedAtInfo(OrigLocation.getNode(), TheCallMD, Context); + + SmallVector MDVs; + MDVs.push_back(InsnMD->getElement(0)); // Line + MDVs.push_back(InsnMD->getElement(1)); // Col + MDVs.push_back(InsnMD->getElement(2)); // Scope + MDVs.push_back(NewLoc); + return MDNode::get(Context, MDVs.data(), MDVs.size()); +} + /// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto, /// except that it does some simple constant prop and DCE on the fly. The /// effect of this is to copy significantly less code in cases where (for @@ -358,7 +380,8 @@ SmallVectorImpl &Returns, const char *NameSuffix, ClonedCodeInfo *CodeInfo, - const TargetData *TD) { + const TargetData *TD, + Instruction *TheCall) { assert(NameSuffix && "NameSuffix cannot be null!"); #ifndef NDEBUG @@ -397,19 +420,49 @@ // references as we go. This uses ValueMap to do all the hard work. // BasicBlock::iterator I = NewBB->begin(); + + LLVMContext &Context = OldFunc->getContext(); + unsigned DbgKind = Context.getMetadata().getMDKind("dbg"); + MDNode *TheCallMD = NULL; + SmallVector MDVs; + if (TheCall && TheCall->hasMetadata()) + TheCallMD = Context.getMetadata().getMD(DbgKind, TheCall); // Handle PHI nodes specially, as we have to remove references to dead // blocks. if (PHINode *PN = dyn_cast(I)) { // Skip over all PHI nodes, remembering them for later. BasicBlock::const_iterator OldI = BI->begin(); - for (; (PN = dyn_cast(I)); ++I, ++OldI) + for (; (PN = dyn_cast(I)); ++I, ++OldI) { + if (I->hasMetadata()) + if (TheCallMD) { + if (MDNode *IMD = Context.getMetadata().getMD(DbgKind, I)) { + MDNode *NewMD = UpdateInlinedAtInfo(IMD, TheCallMD, Context); + Context.getMetadata().addMD(DbgKind, NewMD, I); + } + } else + // The cloned instruction has dbg info but the call instruction + // does not have dbg info. Remove dbg info from cloned instruction. + Context.getMetadata().removeMD(DbgKind, I); PHIToResolve.push_back(cast(OldI)); + } } // Otherwise, remap the rest of the instructions normally. - for (; I != NewBB->end(); ++I) + for (; I != NewBB->end(); ++I) { + if (I->hasMetadata()) + if (TheCallMD) { + if (MDNode *IMD = Context.getMetadata().getMD(DbgKind, I)) { + MDNode *NewMD = UpdateInlinedAtInfo(IMD, TheCallMD, Context); + Context.getMetadata().addMD(DbgKind, NewMD, I); + } + } else + // The cloned instruction has dbg info but the call instruction + // does not have dbg info. Remove dbg info from cloned instruction. + Context.getMetadata().removeMD(DbgKind, I); + RemapInstruction(I, ValueMap); + } } // Defer PHI resolution until rest of function is resolved, PHI resolution Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=86748&r1=86747&r2=86748&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Tue Nov 10 17:06:00 2009 @@ -386,7 +386,7 @@ // (which can happen, e.g., because an argument was constant), but we'll be // happy with whatever the cloner can do. CloneAndPruneFunctionInto(Caller, CalledFunc, ValueMap, Returns, ".i", - &InlinedFunctionInfo, TD); + &InlinedFunctionInfo, TD, TheCall); // Remember the first block that is newly cloned over. FirstNewBlock = LastBlock; ++FirstNewBlock; From dpatel at apple.com Tue Nov 10 17:07:00 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 10 Nov 2009 23:07:00 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r86749 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-debug.cpp llvm-debug.h Message-ID: <200911102307.nAAN71xq006494@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 10 17:07:00 2009 New Revision: 86749 URL: http://llvm.org/viewvc/llvm-project?rev=86749&view=rev Log: Attach locatin info with llvm.dbg.declare. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp llvm-gcc-4.2/trunk/gcc/llvm-debug.h Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=86749&r1=86748&r2=86749&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Nov 10 17:07:00 2009 @@ -304,7 +304,7 @@ TheDebugInfo->EmitDeclare(ResultDecl, dwarf::DW_TAG_return_variable, "agg.result", RetTy, Tmp, - Builder.GetInsertBlock()); + Builder); } ++AI; } @@ -602,7 +602,7 @@ if (!isInvRef && TheDebugInfo) TheDebugInfo->EmitDeclare(Args, dwarf::DW_TAG_arg_variable, Name, TREE_TYPE(Args), - AI, Builder.GetInsertBlock()); + AI, Builder); ++AI; } else { // Otherwise, we create an alloca to hold the argument value and provide @@ -614,7 +614,7 @@ if (TheDebugInfo) { TheDebugInfo->EmitDeclare(Args, dwarf::DW_TAG_arg_variable, Name, TREE_TYPE(Args), Tmp, - Builder.GetInsertBlock()); + Builder); } // Emit annotate intrinsic if arg has annotate attr @@ -646,6 +646,9 @@ // Not supported yet. } + if (TheDebugInfo) + TheDebugInfo->EmitStopPoint(Fn, Builder.GetInsertBlock(), Builder); + // As it turns out, not all temporaries are associated with blocks. For those // that aren't, emit them now. for (tree t = cfun->unexpanded_var_list; t; t = TREE_CHAIN(t)) { @@ -1656,11 +1659,11 @@ if (DECL_NAME(decl)) { TheDebugInfo->EmitDeclare(decl, dwarf::DW_TAG_auto_variable, Name, TREE_TYPE(decl), AI, - Builder.GetInsertBlock()); + Builder); } else if (TREE_CODE(decl) == RESULT_DECL) { TheDebugInfo->EmitDeclare(decl, dwarf::DW_TAG_return_variable, Name, TREE_TYPE(decl), AI, - Builder.GetInsertBlock()); + Builder); } } } Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=86749&r1=86748&r2=86749&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Tue Nov 10 17:07:00 2009 @@ -309,7 +309,8 @@ /// EmitDeclare - Constructs the debug code for allocation of a new variable. /// region - "llvm.dbg.declare." void DebugInfo::EmitDeclare(tree decl, unsigned Tag, const char *Name, - tree type, Value *AI, BasicBlock *CurBB) { + tree type, Value *AI, + LLVMBuilder &Builder) { // Do not emit variable declaration info, for now. if (optimize) @@ -330,7 +331,9 @@ Loc.line, getOrCreateType(type)); // Insert an llvm.dbg.declare into the current block. - DebugFactory.InsertDeclare(AI, D, CurBB); + Instruction *Call = DebugFactory.InsertDeclare(AI, D, + Builder.GetInsertBlock()); + Builder.SetDebugLocation(Call); } Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.h?rev=86749&r1=86748&r2=86749&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.h Tue Nov 10 17:07:00 2009 @@ -92,8 +92,7 @@ /// EmitDeclare - Constructs the debug code for allocation of a new variable. /// region - "llvm.dbg.declare." void EmitDeclare(tree_node *decl, unsigned Tag, const char *Name, - tree_node *type, Value *AI, - BasicBlock *CurBB); + tree_node *type, Value *AI, LLVMBuilder &Builder); /// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of /// source line. From dalej at apple.com Tue Nov 10 17:16:41 2009 From: dalej at apple.com (Dale Johannesen) Date: Tue, 10 Nov 2009 23:16:41 -0000 Subject: [llvm-commits] [llvm] r86751 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp test/CodeGen/PowerPC/vec_auto_constant.ll Message-ID: <200911102316.nAANGfeJ006865@zion.cs.uiuc.edu> Author: johannes Date: Tue Nov 10 17:16:41 2009 New Revision: 86751 URL: http://llvm.org/viewvc/llvm-project?rev=86751&view=rev Log: Emit correct code when making a ConstantPool entry for a vector constant whose component type is not a legal type for the target. (If the target ConstantPool cannot handle this type either, it has an opportunity to merge elements. In practice any target with 8-bit bytes must support i8 *as data*). 7320806 (partial). Added: llvm/trunk/test/CodeGen/PowerPC/vec_auto_constant.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=86751&r1=86750&r2=86751&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Nov 10 17:16:41 2009 @@ -1813,10 +1813,19 @@ CV.push_back(const_cast(V->getConstantFPValue())); } else if (ConstantSDNode *V = dyn_cast(Node->getOperand(i))) { - CV.push_back(const_cast(V->getConstantIntValue())); + if (OpVT==EltVT) + CV.push_back(const_cast(V->getConstantIntValue())); + else { + // If OpVT and EltVT don't match, EltVT is not legal and the + // element values have been promoted/truncated earlier. Undo this; + // we don't want a v16i8 to become a v16i32 for example. + const ConstantInt *CI = V->getConstantIntValue(); + CV.push_back(ConstantInt::get(EltVT.getTypeForEVT(*DAG.getContext()), + CI->getZExtValue())); + } } else { assert(Node->getOperand(i).getOpcode() == ISD::UNDEF); - const Type *OpNTy = OpVT.getTypeForEVT(*DAG.getContext()); + const Type *OpNTy = EltVT.getTypeForEVT(*DAG.getContext()); CV.push_back(UndefValue::get(OpNTy)); } } Added: llvm/trunk/test/CodeGen/PowerPC/vec_auto_constant.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/vec_auto_constant.ll?rev=86751&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/vec_auto_constant.ll (added) +++ llvm/trunk/test/CodeGen/PowerPC/vec_auto_constant.ll Tue Nov 10 17:16:41 2009 @@ -0,0 +1,36 @@ +; RUN: llc < %s -march=ppc32 -mtriple=powerpc-apple-darwin -mcpu=g5 | FileCheck %s +; Formerly produced .long, 7320806 (partial) +; CHECK: .byte 22 +; CHECK: .byte 21 +; CHECK: .byte 20 +; CHECK: .byte 3 +; CHECK: .byte 25 +; CHECK: .byte 24 +; CHECK: .byte 23 +; CHECK: .byte 3 +; CHECK: .byte 28 +; CHECK: .byte 27 +; CHECK: .byte 26 +; CHECK: .byte 3 +; CHECK: .byte 31 +; CHECK: .byte 30 +; CHECK: .byte 29 +; CHECK: .byte 3 + at baz = common global <16 x i8> zeroinitializer ; <<16 x i8>*> [#uses=1] + +define void @foo(<16 x i8> %x) nounwind ssp { +entry: + %x_addr = alloca <16 x i8> ; <<16 x i8>*> [#uses=2] + %temp = alloca <16 x i8> ; <<16 x i8>*> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store <16 x i8> %x, <16 x i8>* %x_addr + store <16 x i8> , <16 x i8>* %temp, align 16 + %0 = load <16 x i8>* %x_addr, align 16 ; <<16 x i8>> [#uses=1] + %1 = load <16 x i8>* %temp, align 16 ; <<16 x i8>> [#uses=1] + %tmp = add <16 x i8> %0, %1 ; <<16 x i8>> [#uses=1] + store <16 x i8> %tmp, <16 x i8>* @baz, align 16 + br label %return + +return: ; preds = %entry + ret void +} From isanbard at gmail.com Tue Nov 10 17:18:33 2009 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 10 Nov 2009 23:18:33 -0000 Subject: [llvm-commits] [llvm] r86752 - /llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll Message-ID: <200911102318.nAANIX7t006938@zion.cs.uiuc.edu> Author: void Date: Tue Nov 10 17:18:33 2009 New Revision: 86752 URL: http://llvm.org/viewvc/llvm-project?rev=86752&view=rev Log: Test this on Darwin only. Modified: llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll Modified: llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll?rev=86752&r1=86751&r2=86752&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll Tue Nov 10 17:18:33 2009 @@ -1,4 +1,6 @@ ; RUN: llc < %s -march=ppc32 -disable-fp-elim | FileCheck %s +; XFAIL: * +; XTARGET: darwin define i32 @_Z4funci(i32 %a) ssp { ; CHECK: mflr r0 From dpatel at apple.com Tue Nov 10 17:20:05 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 10 Nov 2009 23:20:05 -0000 Subject: [llvm-commits] [llvm] r86753 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Message-ID: <200911102320.nAANK5sX007003@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 10 17:20:04 2009 New Revision: 86753 URL: http://llvm.org/viewvc/llvm-project?rev=86753&view=rev Log: Ignore variable if scope info is not available. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=86753&r1=86752&r2=86753&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Nov 10 17:20:04 2009 @@ -1453,7 +1453,8 @@ DIGlobalVariable GV(N); if (GV.getContext().getNode() == SPNode) { DIE *ScopedGVDie = CreateGlobalVariableDIE(ModuleCU, GV); - SPDie->AddChild(ScopedGVDie); + if (ScopedGVDie) + SPDie->AddChild(ScopedGVDie); } } return SPDie; @@ -2076,7 +2077,9 @@ ConcreteScopes.lookup(ScopeLoc.getOrigLocation().getNode()); if (!Scope) Scope = DbgScopeMap.lookup(ScopeLoc.getScope().getNode()); - assert (Scope && "Unable to find variable scope!"); + // If variable scope is not found then skip this variable. + if (!Scope) + continue; DbgVariable *RegVar = new DbgVariable(DV, VP.first); Scope->AddVariable(RegVar); From anton at korobeynikov.info Tue Nov 10 17:30:47 2009 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Wed, 11 Nov 2009 02:30:47 +0300 Subject: [llvm-commits] [llvm] r86752 - /llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll In-Reply-To: <200911102318.nAANIX7t006938@zion.cs.uiuc.edu> References: <200911102318.nAANIX7t006938@zion.cs.uiuc.edu> Message-ID: > URL: http://llvm.org/viewvc/llvm-project?rev=86752&view=rev > Log: > Test this on Darwin only. Why? -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From clattner at apple.com Tue Nov 10 17:36:44 2009 From: clattner at apple.com (Chris Lattner) Date: Tue, 10 Nov 2009 15:36:44 -0800 Subject: [llvm-commits] [llvm] r86752 - /llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll In-Reply-To: <200911102318.nAANIX7t006938@zion.cs.uiuc.edu> References: <200911102318.nAANIX7t006938@zion.cs.uiuc.edu> Message-ID: <1DDDB4CD-4B98-4888-B950-0AC1EB147C3A@apple.com> This should specify a triple for the test (mtriple) not xfail. -chris On Nov 10, 2009, at 3:18 PM, Bill Wendling wrote: > Author: void > Date: Tue Nov 10 17:18:33 2009 > New Revision: 86752 > > URL: http://llvm.org/viewvc/llvm-project?rev=86752&view=rev > Log: > Test this on Darwin only. > > Modified: > llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll > > Modified: llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll?rev=86752&r1=86751&r2=86752&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll (original) > +++ llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll Tue Nov 10 > 17:18:33 2009 > @@ -1,4 +1,6 @@ > ; RUN: llc < %s -march=ppc32 -disable-fp-elim | FileCheck %s > +; XFAIL: * > +; XTARGET: darwin > > define i32 @_Z4funci(i32 %a) ssp { > ; CHECK: mflr r0 > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Tue Nov 10 17:40:49 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 23:40:49 -0000 Subject: [llvm-commits] [llvm] r86754 - /llvm/trunk/lib/Target/README.txt Message-ID: <200911102340.nAANen9E007765@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 17:40:49 2009 New Revision: 86754 URL: http://llvm.org/viewvc/llvm-project?rev=86754&view=rev Log: I did this a week or two ago Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=86754&r1=86753&r2=86754&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Tue Nov 10 17:40:49 2009 @@ -1612,12 +1612,6 @@ //===---------------------------------------------------------------------===// -IPSCCP is propagating elements of first class aggregates, but is not propagating -the entire aggregate itself. This leads it to miss opportunities, for example -in test/Transforms/SCCP/ipsccp-basic.ll:test5b. - -//===---------------------------------------------------------------------===// - int func(int a, int b) { if (a & 0x80) b |= 0x80; else b &= ~0x80; return b; } Generates this: From sabre at nondot.org Tue Nov 10 17:47:45 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 23:47:45 -0000 Subject: [llvm-commits] [llvm] r86756 - /llvm/trunk/lib/Target/README.txt Message-ID: <200911102347.nAANljSu008010@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 17:47:45 2009 New Revision: 86756 URL: http://llvm.org/viewvc/llvm-project?rev=86756&view=rev Log: add a note Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=86756&r1=86755&r2=86756&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Tue Nov 10 17:47:45 2009 @@ -339,6 +339,8 @@ extra register for the function when effective_addr2 is declared as U64 than when it is declared U32. +PHI Slicing could be extended to do this. + //===---------------------------------------------------------------------===// LSR should know what GPR types a target has. This code: From sabre at nondot.org Tue Nov 10 17:54:10 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 23:54:10 -0000 Subject: [llvm-commits] [llvm] r86758 - /llvm/trunk/include/llvm/Support/StandardPasses.h Message-ID: <200911102354.nAANsARq008321@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 17:54:10 2009 New Revision: 86758 URL: http://llvm.org/viewvc/llvm-project?rev=86758&view=rev Log: jump threading does everything that condprop does any more. This passes bootstrap on darwin i386. Modified: llvm/trunk/include/llvm/Support/StandardPasses.h Modified: llvm/trunk/include/llvm/Support/StandardPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=86758&r1=86757&r2=86758&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) +++ llvm/trunk/include/llvm/Support/StandardPasses.h Tue Nov 10 17:54:10 2009 @@ -125,8 +125,6 @@ PM->add(createCFGSimplificationPass()); // Merge & remove BBs PM->add(createInstructionCombiningPass()); // Combine silly seq's - // FIXME: CondProp breaks critical edges, which is slow. - PM->add(createCondPropagationPass()); // Propagate conditionals PM->add(createTailCallEliminationPass()); // Eliminate tail calls PM->add(createCFGSimplificationPass()); // Merge & remove BBs PM->add(createReassociatePass()); // Reassociate expressions @@ -146,7 +144,7 @@ // Run instcombine after redundancy elimination to exploit opportunities // opened up by them. PM->add(createInstructionCombiningPass()); - PM->add(createCondPropagationPass()); // Propagate conditionals + PM->add(createJumpThreadingPass()); // Thread jumps PM->add(createDeadStoreEliminationPass()); // Delete dead stores PM->add(createAggressiveDCEPass()); // Delete dead instructions PM->add(createCFGSimplificationPass()); // Merge & remove BBs From sabre at nondot.org Tue Nov 10 17:54:41 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 23:54:41 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r86759 - /llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Message-ID: <200911102354.nAANsgHI008350@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 17:54:41 2009 New Revision: 86759 URL: http://llvm.org/viewvc/llvm-project?rev=86759&view=rev Log: no need to link in condprop Modified: llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp?rev=86759&r1=86758&r2=86759&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Tue Nov 10 17:54:41 2009 @@ -75,7 +75,6 @@ llvm::createAggressiveDCEPass(); llvm::createConstantMergePass(); llvm::createIndVarSimplifyPass(); - llvm::createCondPropagationPass(); llvm::createGlobalOptimizerPass(); llvm::createJumpThreadingPass(); llvm::createFunctionInliningPass(); From evan.cheng at apple.com Tue Nov 10 18:00:21 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 11 Nov 2009 00:00:21 -0000 Subject: [llvm-commits] [llvm] r86761 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2009-11-10-LSRCrash.ll Message-ID: <200911110000.nAB00LTk008585@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 10 18:00:21 2009 New Revision: 86761 URL: http://llvm.org/viewvc/llvm-project?rev=86761&view=rev Log: Block terminator may be a switch. Added: llvm/trunk/test/Transforms/LoopStrengthReduce/2009-11-10-LSRCrash.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=86761&r1=86760&r2=86761&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue Nov 10 18:00:21 2009 @@ -2428,7 +2428,7 @@ if (!L->isLoopExiting(CondBB)) return false; BranchInst *TermBr = dyn_cast(CondBB->getTerminator()); - if (!TermBr->isConditional()) + if (!TermBr || !TermBr->isConditional()) return false; Value *User = *Cond->use_begin(); Added: llvm/trunk/test/Transforms/LoopStrengthReduce/2009-11-10-LSRCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopStrengthReduce/2009-11-10-LSRCrash.ll?rev=86761&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopStrengthReduce/2009-11-10-LSRCrash.ll (added) +++ llvm/trunk/test/Transforms/LoopStrengthReduce/2009-11-10-LSRCrash.ll Tue Nov 10 18:00:21 2009 @@ -0,0 +1,130 @@ +; RUN: llc < %s -mtriple=i386-apple-darwin11 + +define void @_ZN4llvm20SelectionDAGLowering14visitInlineAsmENS_8CallSiteE() nounwind ssp align 2 { +entry: + br i1 undef, label %bb3.i, label %bb4.i + +bb3.i: ; preds = %entry + unreachable + +bb4.i: ; preds = %entry + br i1 undef, label %bb.i.i, label %_ZNK4llvm8CallSite14getCalledValueEv.exit + +bb.i.i: ; preds = %bb4.i + unreachable + +_ZNK4llvm8CallSite14getCalledValueEv.exit: ; preds = %bb4.i + br i1 undef, label %_ZN4llvm4castINS_9InlineAsmEPNS_5ValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS6_.exit, label %bb6.i + +bb6.i: ; preds = %_ZNK4llvm8CallSite14getCalledValueEv.exit + unreachable + +_ZN4llvm4castINS_9InlineAsmEPNS_5ValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS6_.exit: ; preds = %_ZNK4llvm8CallSite14getCalledValueEv.exit + br i1 undef, label %_ZL25hasInlineAsmMemConstraintRSt6vectorIN4llvm9InlineAsm14ConstraintInfoESaIS2_EERKNS0_14TargetLoweringE.exit, label %bb.i + +bb.i: ; preds = %_ZN4llvm4castINS_9InlineAsmEPNS_5ValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS6_.exit + br label %_ZL25hasInlineAsmMemConstraintRSt6vectorIN4llvm9InlineAsm14ConstraintInfoESaIS2_EERKNS0_14TargetLoweringE.exit + +_ZL25hasInlineAsmMemConstraintRSt6vectorIN4llvm9InlineAsm14ConstraintInfoESaIS2_EERKNS0_14TargetLoweringE.exit: ; preds = %bb.i, %_ZN4llvm4castINS_9InlineAsmEPNS_5ValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS6_.exit + br i1 undef, label %bb50, label %bb27 + +bb27: ; preds = %_ZL25hasInlineAsmMemConstraintRSt6vectorIN4llvm9InlineAsm14ConstraintInfoESaIS2_EERKNS0_14TargetLoweringE.exit + br i1 undef, label %bb1.i727, label %bb.i.i726 + +bb.i.i726: ; preds = %bb27 + unreachable + +bb1.i727: ; preds = %bb27 + unreachable + +bb50: ; preds = %_ZL25hasInlineAsmMemConstraintRSt6vectorIN4llvm9InlineAsm14ConstraintInfoESaIS2_EERKNS0_14TargetLoweringE.exit + br label %bb107 + +bb51: ; preds = %bb107 + br i1 undef, label %bb105, label %bb106 + +bb105: ; preds = %bb51 + unreachable + +bb106: ; preds = %bb51 + br label %bb107 + +bb107: ; preds = %bb106, %bb50 + br i1 undef, label %bb108, label %bb51 + +bb108: ; preds = %bb107 + br i1 undef, label %bb242, label %bb114 + +bb114: ; preds = %bb108 + br i1 undef, label %bb141, label %bb116 + +bb116: ; preds = %bb114 + br i1 undef, label %bb120, label %bb121 + +bb120: ; preds = %bb116 + unreachable + +bb121: ; preds = %bb116 + unreachable + +bb141: ; preds = %bb114 + br i1 undef, label %bb182, label %bb143 + +bb143: ; preds = %bb141 + br label %bb157 + +bb144: ; preds = %bb.i.i.i843 + switch i32 undef, label %bb155 [ + i32 2, label %bb153 + i32 6, label %bb153 + i32 4, label %bb153 + ] + +bb153: ; preds = %bb144, %bb144, %bb144 + %indvar.next = add i32 %indvar, 1 ; [#uses=1] + br label %bb157 + +bb155: ; preds = %bb144 + unreachable + +bb157: ; preds = %bb153, %bb143 + %indvar = phi i32 [ %indvar.next, %bb153 ], [ 0, %bb143 ] ; [#uses=2] + %0 = icmp eq i32 undef, %indvar ; [#uses=1] + switch i16 undef, label %bb6.i841 [ + i16 9, label %_ZN4llvm4castINS_14ConstantSDNodeENS_7SDValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS5_.exit + i16 26, label %_ZN4llvm4castINS_14ConstantSDNodeENS_7SDValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS5_.exit + ] + +bb6.i841: ; preds = %bb157 + unreachable + +_ZN4llvm4castINS_14ConstantSDNodeENS_7SDValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS5_.exit: ; preds = %bb157, %bb157 + br i1 undef, label %bb.i.i.i843, label %bb1.i.i.i844 + +bb.i.i.i843: ; preds = %_ZN4llvm4castINS_14ConstantSDNodeENS_7SDValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS5_.exit + br i1 %0, label %bb158, label %bb144 + +bb1.i.i.i844: ; preds = %_ZN4llvm4castINS_14ConstantSDNodeENS_7SDValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS5_.exit + unreachable + +bb158: ; preds = %bb.i.i.i843 + br i1 undef, label %bb177, label %bb176 + +bb176: ; preds = %bb158 + unreachable + +bb177: ; preds = %bb158 + br i1 undef, label %bb179, label %bb178 + +bb178: ; preds = %bb177 + unreachable + +bb179: ; preds = %bb177 + unreachable + +bb182: ; preds = %bb141 + unreachable + +bb242: ; preds = %bb108 + unreachable +} From dpatel at apple.com Tue Nov 10 18:18:40 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 11 Nov 2009 00:18:40 -0000 Subject: [llvm-commits] [llvm] r86763 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp test/DebugInfo/2009-11-10-ParentScope.ll Message-ID: <200911110018.nAB0Iel8009212@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 10 18:18:40 2009 New Revision: 86763 URL: http://llvm.org/viewvc/llvm-project?rev=86763&view=rev Log: While creating DbgScopes, do not forget parent scope. Added: llvm/trunk/test/DebugInfo/2009-11-10-ParentScope.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=86763&r1=86762&r2=86763&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Nov 10 18:18:40 2009 @@ -2124,6 +2124,8 @@ return; WScope = new DbgScope(NULL, DIDescriptor(Scope), NULL); DbgScopeMap.insert(std::make_pair(Scope, WScope)); + if (DIDescriptor(Scope).isLexicalBlock()) + createDbgScope(DILexicalBlock(Scope).getContext().getNode(), NULL); return; } Added: llvm/trunk/test/DebugInfo/2009-11-10-ParentScope.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2009-11-10-ParentScope.ll?rev=86763&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2009-11-10-ParentScope.ll (added) +++ llvm/trunk/test/DebugInfo/2009-11-10-ParentScope.ll Tue Nov 10 18:18:40 2009 @@ -0,0 +1,26 @@ +; RUN: llc < %s -o /dev/null +%struct.htab = type { i32 (i8*)*, i32 (i8*, i8*)*, void (i8*)*, i8**, i64, i64, i64, i32, i32, i8* (i64, i64)*, void (i8*)*, i8*, i8* (i8*, i64, i64)*, void (i8*, i8*)*, i32, [4 x i8] } + +define i8* @htab_find_with_hash(%struct.htab* %htab, i8* %element, i32 %hash) nounwind { +entry: + br i1 undef, label %land.lhs.true, label %if.end, !dbg !0 + +land.lhs.true: ; preds = %entry + unreachable + +if.end: ; preds = %entry + store i8* undef, i8** undef, !dbg !7 + ret i8* undef, !dbg !10 +} + +!0 = metadata !{i32 571, i32 3, metadata !1, null} +!1 = metadata !{i32 458763, metadata !2}; [DW_TAG_lexical_block ] +!2 = metadata !{i32 458798, i32 0, metadata !3, metadata !"htab_find_with_hash", metadata !"htab_find_with_hash", metadata !"htab_find_with_hash", metadata !3, i32 561, metadata !4, i1 false, i1 true}; [DW_TAG_subprogram ] +!3 = metadata !{i32 458769, i32 0, i32 12, metadata !"hashtab.c", metadata !"/usr/src/gnu/usr.bin/cc/cc_tools/../../../../contrib/gcclibs/libiberty", metadata !"clang 1.1", i1 true, i1 false, metadata !"", i32 0}; [DW_TAG_compile_unit ] +!4 = metadata !{i32 458773, metadata !3, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0}; [DW_TAG_subroutine_type ] +!5 = metadata !{metadata !6} +!6 = metadata !{i32 458767, metadata !3, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, null}; [DW_TAG_pointer_type ] +!7 = metadata !{i32 583, i32 7, metadata !8, null} +!8 = metadata !{i32 458763, metadata !9}; [DW_TAG_lexical_block ] +!9 = metadata !{i32 458763, metadata !1}; [DW_TAG_lexical_block ] +!10 = metadata !{i32 588, i32 1, metadata !2, null} From sabre at nondot.org Tue Nov 10 18:21:22 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 00:21:22 -0000 Subject: [llvm-commits] [llvm] r86765 - in /llvm/trunk: include/llvm/Analysis/LiveValues.h lib/Analysis/LiveValues.cpp Message-ID: <200911110021.nAB0LM2f009348@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 18:21:21 2009 New Revision: 86765 URL: http://llvm.org/viewvc/llvm-project?rev=86765&view=rev Log: remove redundant foward declaration. This function is already in Analysis/Passes.h Modified: llvm/trunk/include/llvm/Analysis/LiveValues.h llvm/trunk/lib/Analysis/LiveValues.cpp Modified: llvm/trunk/include/llvm/Analysis/LiveValues.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LiveValues.h?rev=86765&r1=86764&r2=86765&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LiveValues.h (original) +++ llvm/trunk/include/llvm/Analysis/LiveValues.h Tue Nov 10 18:21:21 2009 @@ -94,10 +94,6 @@ bool isKilledInBlock(const Value *V, const BasicBlock *BB); }; -/// createLiveValuesPass - This creates an instance of the LiveValues pass. -/// -FunctionPass *createLiveValuesPass(); - -} +} // end namespace llvm #endif Modified: llvm/trunk/lib/Analysis/LiveValues.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LiveValues.cpp?rev=86765&r1=86764&r2=86765&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LiveValues.cpp (original) +++ llvm/trunk/lib/Analysis/LiveValues.cpp Tue Nov 10 18:21:21 2009 @@ -17,7 +17,9 @@ #include "llvm/Analysis/LoopInfo.h" using namespace llvm; -FunctionPass *llvm::createLiveValuesPass() { return new LiveValues(); } +namespace llvm { + FunctionPass *createLiveValuesPass() { return new LiveValues(); } +} char LiveValues::ID = 0; static RegisterPass From sabre at nondot.org Tue Nov 10 18:21:59 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 00:21:59 -0000 Subject: [llvm-commits] [llvm] r86766 - /llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200911110021.nAB0Lxfh009400@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 18:21:58 2009 New Revision: 86766 URL: http://llvm.org/viewvc/llvm-project?rev=86766&view=rev Log: add a fixme Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86766&r1=86765&r2=86766&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Tue Nov 10 18:21:58 2009 @@ -169,6 +169,10 @@ /// Ignore PHI nodes, these will be flattened when duplication happens. BasicBlock::const_iterator I = BB->getFirstNonPHI(); + // FIXME: THREADING will delete values that are just used to compute the + // branch, so they shouldn't count against the duplication cost. + + // Sum up the cost of each instruction until we get to the terminator. Don't // include the terminator because the copy won't include it. unsigned Size = 0; From sabre at nondot.org Tue Nov 10 18:22:30 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 00:22:30 -0000 Subject: [llvm-commits] [llvm] r86767 - in /llvm/trunk: include/llvm/Analysis/LazyValueInfo.h include/llvm/Analysis/Passes.h include/llvm/LinkAllPasses.h lib/Analysis/CMakeLists.txt lib/Analysis/LazyValueInfo.cpp test/Transforms/JumpThreading/basic.ll Message-ID: <200911110022.nAB0MVa4009438@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 18:22:30 2009 New Revision: 86767 URL: http://llvm.org/viewvc/llvm-project?rev=86767&view=rev Log: Stub out a new lazy value info pass, which will eventually vend value constraint information to the optimizer. Added: llvm/trunk/include/llvm/Analysis/LazyValueInfo.h llvm/trunk/lib/Analysis/LazyValueInfo.cpp Modified: llvm/trunk/include/llvm/Analysis/Passes.h llvm/trunk/include/llvm/LinkAllPasses.h llvm/trunk/lib/Analysis/CMakeLists.txt llvm/trunk/test/Transforms/JumpThreading/basic.ll Added: llvm/trunk/include/llvm/Analysis/LazyValueInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LazyValueInfo.h?rev=86767&view=auto ============================================================================== --- llvm/trunk/include/llvm/Analysis/LazyValueInfo.h (added) +++ llvm/trunk/include/llvm/Analysis/LazyValueInfo.h Tue Nov 10 18:22:30 2009 @@ -0,0 +1,43 @@ +//===- LazyValueInfo.h - Value constraint analysis --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the interface for lazy computation of value constraint +// information. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_LIVEVALUES_H +#define LLVM_ANALYSIS_LIVEVALUES_H + +#include "llvm/Pass.h" + +namespace llvm { + +/// LazyValueInfo - This pass computes, caches, and vends lazy value constraint +/// information. +class LazyValueInfo : public FunctionPass { +public: + static char ID; + LazyValueInfo(); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } + virtual void releaseMemory(); + + virtual bool runOnFunction(Function &F) { + // Fully lazy. + return false; + } +}; + +} // end namespace llvm + +#endif + Modified: llvm/trunk/include/llvm/Analysis/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Passes.h?rev=86767&r1=86766&r2=86767&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/Passes.h (original) +++ llvm/trunk/include/llvm/Analysis/Passes.h Tue Nov 10 18:22:30 2009 @@ -139,6 +139,12 @@ // createLiveValuesPass - This creates an instance of the LiveValues pass. // FunctionPass *createLiveValuesPass(); + + //===--------------------------------------------------------------------===// + // + /// createLazyValueInfoPass - This creates an instance of the LazyValueInfo + /// pass. + FunctionPass *createLazyValueInfoPass(); //===--------------------------------------------------------------------===// // Modified: llvm/trunk/include/llvm/LinkAllPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=86767&r1=86766&r2=86767&view=diff ============================================================================== --- llvm/trunk/include/llvm/LinkAllPasses.h (original) +++ llvm/trunk/include/llvm/LinkAllPasses.h Tue Nov 10 18:22:30 2009 @@ -82,6 +82,7 @@ (void) llvm::createInternalizePass(false); (void) llvm::createLCSSAPass(); (void) llvm::createLICMPass(); + (void) llvm::createLazyValueInfoPass(); (void) llvm::createLiveValuesPass(); (void) llvm::createLoopDependenceAnalysisPass(); (void) llvm::createLoopExtractorPass(); Modified: llvm/trunk/lib/Analysis/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=86767&r1=86766&r2=86767&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/CMakeLists.txt (original) +++ llvm/trunk/lib/Analysis/CMakeLists.txt Tue Nov 10 18:22:30 2009 @@ -18,6 +18,7 @@ InstructionSimplify.cpp Interval.cpp IntervalPartition.cpp + LazyValueInfo.cpp LibCallAliasAnalysis.cpp LibCallSemantics.cpp LiveValues.cpp Added: llvm/trunk/lib/Analysis/LazyValueInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=86767&view=auto ============================================================================== --- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (added) +++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Tue Nov 10 18:22:30 2009 @@ -0,0 +1,31 @@ +//===- LazyValueInfo.cpp - Value constraint analysis ----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the interface for lazy computation of value constraint +// information. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/LazyValueInfo.h" +using namespace llvm; + +char LazyValueInfo::ID = 0; +static RegisterPass +X("lazy-value-info", "Lazy Value Information Analysis", false, true); + +namespace llvm { + FunctionPass *createLazyValueInfoPass() { return new LazyValueInfo(); } +} + +LazyValueInfo::LazyValueInfo() : FunctionPass(&ID) { +} + +void LazyValueInfo::releaseMemory() { + +} Modified: llvm/trunk/test/Transforms/JumpThreading/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/basic.ll?rev=86767&r1=86766&r2=86767&view=diff ============================================================================== --- llvm/trunk/test/Transforms/JumpThreading/basic.ll (original) +++ llvm/trunk/test/Transforms/JumpThreading/basic.ll Tue Nov 10 18:22:30 2009 @@ -284,3 +284,29 @@ } + + +;;; Duplicate condition to avoid xor of cond. +define i32 @test10(i1 %cond, i1 %cond2) { +Entry: +; CHECK: @test10 + %v1 = call i32 @f1() + br i1 %cond, label %Merge, label %F1 + +F1: + br label %Merge + +Merge: + %B = phi i1 [true, %Entry], [%cond2, %F1] + %M = icmp eq i32 %v1, 192 + %N = xor i1 %B, %M + br i1 %N, label %T2, label %F2 + +T2: + ret i32 123 + +F2: + ret i32 %v1 +} + + From espindola at google.com Tue Nov 10 18:25:45 2009 From: espindola at google.com (Rafael Espindola) Date: Tue, 10 Nov 2009 19:25:45 -0500 Subject: [llvm-commits] [PATCH] LTO code generator options In-Reply-To: <9C7CA4093A8F41D7AD156ED3CF854D17@andreic6e7fe55> References: <04F6B1512E264B27AEE607542FCDD113@andreic6e7fe55> <9C7CA4093A8F41D7AD156ED3CF854D17@andreic6e7fe55> Message-ID: <38a0d8450911101625s5e3b7cb0m31ec0ce4d4144dc@mail.gmail.com> 2009/11/10 Viktor Kutuzov : > Is this Ok to submit? Small comments: * StringRef is normally passed by value. * Can you put the header reordering and white space in an independent patch? * Part of the alignment looks strange: + if (!MAttrs.empty()) + features.AddFeatures(MAttrs); * getArchNameForLLVMArchType is not used > Best regards, > Viktor Cheers, -- Rafael ?vila de Esp?ndola From sabre at nondot.org Tue Nov 10 18:27:55 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 00:27:55 -0000 Subject: [llvm-commits] [llvm] r86768 - /llvm/trunk/test/Transforms/JumpThreading/basic.ll Message-ID: <200911110027.nAB0RtlB009606@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 18:27:54 2009 New Revision: 86768 URL: http://llvm.org/viewvc/llvm-project?rev=86768&view=rev Log: oops, didn't mean to commit this, no harm, but add a todoops, didn't mean to commit this, no harm, but add a todoo Modified: llvm/trunk/test/Transforms/JumpThreading/basic.ll Modified: llvm/trunk/test/Transforms/JumpThreading/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/basic.ll?rev=86768&r1=86767&r2=86768&view=diff ============================================================================== --- llvm/trunk/test/Transforms/JumpThreading/basic.ll (original) +++ llvm/trunk/test/Transforms/JumpThreading/basic.ll Tue Nov 10 18:27:54 2009 @@ -287,6 +287,7 @@ ;;; Duplicate condition to avoid xor of cond. +;;; TODO: Make this happen. define i32 @test10(i1 %cond, i1 %cond2) { Entry: ; CHECK: @test10 From daniel at zuster.org Tue Nov 10 18:28:38 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 11 Nov 2009 00:28:38 -0000 Subject: [llvm-commits] [llvm] r86769 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200911110028.nAB0ScGp009640@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 10 18:28:38 2009 New Revision: 86769 URL: http://llvm.org/viewvc/llvm-project?rev=86769&view=rev Log: llvm-gcc/clang don't (won't?) need this hack. Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=86769&r1=86768&r2=86769&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Nov 10 18:28:38 2009 @@ -16,7 +16,8 @@ // // FIXME: This is a huge hack, to work around ridiculously awful compile times // on this file with gcc-4.2 on Darwin, in Release mode. -#if defined(__APPLE__) && defined(__OPTIMIZE__) && !defined(NDEBUG) +#if (!defined(__llvm__) && defined(__APPLE__) && \ + defined(__OPTIMIZE__) && !defined(NDEBUG)) #define NDEBUG #endif From daniel at zuster.org Tue Nov 10 18:28:53 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 11 Nov 2009 00:28:53 -0000 Subject: [llvm-commits] [llvm] r86770 - in /llvm/trunk: include/llvm/ADT/StringRef.h lib/Support/StringRef.cpp unittests/ADT/StringRefTest.cpp Message-ID: <200911110028.nAB0SrIG009661@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 10 18:28:53 2009 New Revision: 86770 URL: http://llvm.org/viewvc/llvm-project?rev=86770&view=rev Log: Add From arguments to StringRef search functions, and tweak doxyments. Also, add unittests for find_first_of and find_first_not_of. Modified: llvm/trunk/include/llvm/ADT/StringRef.h llvm/trunk/lib/Support/StringRef.cpp llvm/trunk/unittests/ADT/StringRefTest.cpp Modified: llvm/trunk/include/llvm/ADT/StringRef.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringRef.h?rev=86770&r1=86769&r2=86770&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/StringRef.h (original) +++ llvm/trunk/include/llvm/ADT/StringRef.h Tue Nov 10 18:28:53 2009 @@ -152,8 +152,8 @@ /// /// \return - The index of the first occurence of \arg C, or npos if not /// found. - size_t find(char C) const { - for (size_t i = 0, e = Length; i != e; ++i) + size_t find(char C, size_t From = 0) const { + for (size_t i = std::min(From, Length), e = Length; i != e; ++i) if (Data[i] == C) return i; return npos; @@ -163,7 +163,7 @@ /// /// \return - The index of the first occurence of \arg Str, or npos if not /// found. - size_t find(StringRef Str) const; + size_t find(StringRef Str, size_t From = 0) const; /// rfind - Search for the last character \arg C in the string. /// @@ -186,17 +186,25 @@ /// found. size_t rfind(StringRef Str) const; - /// find_first_of - Find the first instance of the specified character or - /// return npos if not in string. Same as find. - size_type find_first_of(char C) const { return find(C); } - - /// find_first_of - Find the first character from the string 'Chars' in the - /// current string or return npos if not in string. - size_type find_first_of(StringRef Chars) const; + /// find_first_of - Find the first character in the string that is \arg C, + /// or npos if not found. Same as find. + size_type find_first_of(char C, size_t From = 0) const { return find(C); } + + /// find_first_of - Find the first character in the string that is in \arg + /// Chars, or npos if not found. + /// + /// Note: O(size() * Chars.size()) + size_type find_first_of(StringRef Chars, size_t From = 0) const; + + /// find_first_not_of - Find the first character in the string that is not + /// \arg C or npos if not found. + size_type find_first_not_of(char C, size_t From = 0) const; /// find_first_not_of - Find the first character in the string that is not - /// in the string 'Chars' or return npos if all are in string. Same as find. - size_type find_first_not_of(StringRef Chars) const; + /// in the string \arg Chars, or npos if not found. + /// + /// Note: O(size() * Chars.size()) + size_type find_first_not_of(StringRef Chars, size_t From = 0) const; /// @} /// @name Helpful Algorithms Modified: llvm/trunk/lib/Support/StringRef.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StringRef.cpp?rev=86770&r1=86769&r2=86770&view=diff ============================================================================== --- llvm/trunk/lib/Support/StringRef.cpp (original) +++ llvm/trunk/lib/Support/StringRef.cpp Tue Nov 10 18:28:53 2009 @@ -24,11 +24,11 @@ /// /// \return - The index of the first occurence of \arg Str, or npos if not /// found. -size_t StringRef::find(StringRef Str) const { +size_t StringRef::find(StringRef Str, size_t From) const { size_t N = Str.size(); if (N > Length) return npos; - for (size_t i = 0, e = Length - N + 1; i != e; ++i) + for (size_t e = Length - N + 1, i = std::min(From, e); i != e; ++i) if (substr(i, N).equals(Str)) return i; return npos; @@ -50,19 +50,34 @@ return npos; } -/// find_first_of - Find the first character from the string 'Chars' in the -/// current string or return npos if not in string. -StringRef::size_type StringRef::find_first_of(StringRef Chars) const { - for (size_type i = 0, e = Length; i != e; ++i) +/// find_first_of - Find the first character in the string that is in \arg +/// Chars, or npos if not found. +/// +/// Note: O(size() * Chars.size()) +StringRef::size_type StringRef::find_first_of(StringRef Chars, + size_t From) const { + for (size_type i = std::min(From, Length), e = Length; i != e; ++i) if (Chars.find(Data[i]) != npos) return i; return npos; } /// find_first_not_of - Find the first character in the string that is not -/// in the string 'Chars' or return npos if all are in string. Same as find. -StringRef::size_type StringRef::find_first_not_of(StringRef Chars) const { - for (size_type i = 0, e = Length; i != e; ++i) +/// \arg C or npos if not found. +StringRef::size_type StringRef::find_first_not_of(char C, size_t From) const { + for (size_type i = std::min(From, Length), e = Length; i != e; ++i) + if (Data[i] != C) + return i; + return npos; +} + +/// find_first_not_of - Find the first character in the string that is not +/// in the string \arg Chars, or npos if not found. +/// +/// Note: O(size() * Chars.size()) +StringRef::size_type StringRef::find_first_not_of(StringRef Chars, + size_t From) const { + for (size_type i = std::min(From, Length), e = Length; i != e; ++i) if (Chars.find(Data[i]) == npos) return i; return npos; Modified: llvm/trunk/unittests/ADT/StringRefTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/StringRefTest.cpp?rev=86770&r1=86769&r2=86770&view=diff ============================================================================== --- llvm/trunk/unittests/ADT/StringRefTest.cpp (original) +++ llvm/trunk/unittests/ADT/StringRefTest.cpp Tue Nov 10 18:28:53 2009 @@ -125,6 +125,8 @@ EXPECT_EQ(0U, Str.find("hello")); EXPECT_EQ(1U, Str.find("ello")); EXPECT_EQ(StringRef::npos, Str.find("zz")); + EXPECT_EQ(2U, Str.find("ll", 2)); + EXPECT_EQ(StringRef::npos, Str.find("ll", 3)); EXPECT_EQ(3U, Str.rfind('l')); EXPECT_EQ(StringRef::npos, Str.rfind('z')); @@ -132,6 +134,14 @@ EXPECT_EQ(0U, Str.rfind("hello")); EXPECT_EQ(1U, Str.rfind("ello")); EXPECT_EQ(StringRef::npos, Str.rfind("zz")); + + EXPECT_EQ(2U, Str.find_first_of('l')); + EXPECT_EQ(1U, Str.find_first_of("el")); + EXPECT_EQ(StringRef::npos, Str.find_first_of("xyz")); + + EXPECT_EQ(1U, Str.find_first_not_of('h')); + EXPECT_EQ(4U, Str.find_first_not_of("hel")); + EXPECT_EQ(StringRef::npos, Str.find_first_not_of("hello")); } TEST(StringRefTest, Count) { From dpatel at apple.com Tue Nov 10 18:31:36 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 11 Nov 2009 00:31:36 -0000 Subject: [llvm-commits] [llvm] r86771 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp test/DebugInfo/2009-11-10-CurrentFn.ll Message-ID: <200911110031.nAB0VaMj009767@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 10 18:31:36 2009 New Revision: 86771 URL: http://llvm.org/viewvc/llvm-project?rev=86771&view=rev Log: Do not assume first function scope seen represents current function. Added: llvm/trunk/test/DebugInfo/2009-11-10-CurrentFn.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=86771&r1=86770&r2=86771&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Nov 10 18:31:36 2009 @@ -1347,8 +1347,9 @@ NScope->setFirstInsn(MI); if (!Parent && !InlinedAt) { - assert (!CurrentFnDbgScope && "Unexpected function scope!"); - CurrentFnDbgScope = NScope; + StringRef SPName = DISubprogram(N).getLinkageName(); + if (SPName == MF->getFunction()->getName()) + CurrentFnDbgScope = NScope; } if (GetConcreteScope) { Added: llvm/trunk/test/DebugInfo/2009-11-10-CurrentFn.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2009-11-10-CurrentFn.ll?rev=86771&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2009-11-10-CurrentFn.ll (added) +++ llvm/trunk/test/DebugInfo/2009-11-10-CurrentFn.ll Tue Nov 10 18:31:36 2009 @@ -0,0 +1,19 @@ + +declare void @foo() + +define void @bar(i32 %i) nounwind ssp { +entry: + tail call void @foo() nounwind, !dbg !0 + ret void, !dbg !6 +} + +!0 = metadata !{i32 9, i32 0, metadata !1, null} +!1 = metadata !{i32 458798, i32 0, metadata !2, metadata !"baz", metadata !"baz", metadata !"baz", metadata !2, i32 8, metadata !3, i1 true, i1 true}; [DW_TAG_subprogram ] +!2 = metadata !{i32 458769, i32 0, i32 1, metadata !"2007-12-VarArrayDebug.c", metadata !"/Volumes/Data/ddunbar/llvm/test/FrontendC", metadata !"4.2.1 (Based on Apple Inc. build 5653) (LLVM build)", i1 true, i1 true, metadata !"", i32 0}; [DW_TAG_compile_unit ] +!3 = metadata !{i32 458773, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0}; [DW_TAG_subroutine_type ] +!4 = metadata !{null, metadata !5} +!5 = metadata !{i32 458788, metadata !2, metadata !"int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5}; [DW_TAG_base_type ] +!6 = metadata !{i32 18, i32 0, metadata !7, null} +!7 = metadata !{i32 458798, i32 0, metadata !2, metadata !"bar", metadata !"bar", metadata !"bar", metadata !2, i32 16, metadata !8, i1 false, i1 true}; [DW_TAG_subprogram ] +!8 = metadata !{i32 458773, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !9, i32 0}; [DW_TAG_subroutine_type ] +!9 = metadata !{null} From daniel at zuster.org Tue Nov 10 18:43:14 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 11 Nov 2009 00:43:14 -0000 Subject: [llvm-commits] [llvm] r86773 - /llvm/trunk/include/llvm/ADT/Triple.h Message-ID: <200911110043.nAB0hEe2010196@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 10 18:43:14 2009 New Revision: 86773 URL: http://llvm.org/viewvc/llvm-project?rev=86773&view=rev Log: Add Triple::str() which returns the contents of the Triple as a string, as a more readable alternative to getTriple(). Modified: llvm/trunk/include/llvm/ADT/Triple.h Modified: llvm/trunk/include/llvm/ADT/Triple.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/Triple.h?rev=86773&r1=86772&r2=86773&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/Triple.h (original) +++ llvm/trunk/include/llvm/ADT/Triple.h Tue Nov 10 18:43:14 2009 @@ -160,6 +160,8 @@ /// @name Direct Component Access /// @{ + const std::string &str() const { return Data; } + const std::string &getTriple() const { return Data; } /// getArchName - Get the architecture (first) component of the From isanbard at gmail.com Tue Nov 10 19:24:59 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 11 Nov 2009 01:24:59 -0000 Subject: [llvm-commits] [llvm] r86779 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfException.cpp test/CodeGen/X86/hidden-vis-5.ll Message-ID: <200911110124.nAB1OxY8012160@zion.cs.uiuc.edu> Author: void Date: Tue Nov 10 19:24:59 2009 New Revision: 86779 URL: http://llvm.org/viewvc/llvm-project?rev=86779&view=rev Log: Make sure that the exception handling data has the same visibility as the function it's generated for. Added: llvm/trunk/test/CodeGen/X86/hidden-vis-5.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp?rev=86779&r1=86778&r2=86779&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Tue Nov 10 19:24:59 2009 @@ -232,11 +232,16 @@ // corresponding function is static, this should not be externally visible. if (!TheFunc->hasLocalLinkage()) if (const char *GlobalEHDirective = MAI->getGlobalEHDirective()) - O << GlobalEHDirective << EHFrameInfo.FnName << "\n"; + O << GlobalEHDirective << EHFrameInfo.FnName << '\n'; // If corresponding function is weak definition, this should be too. if (TheFunc->isWeakForLinker() && MAI->getWeakDefDirective()) - O << MAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n"; + O << MAI->getWeakDefDirective() << EHFrameInfo.FnName << '\n'; + + // If corresponding function is hidden, this should be too. + if (TheFunc->hasHiddenVisibility()) + if (const char *HiddenDirective = MAI->getHiddenDirective()) + O << HiddenDirective << EHFrameInfo.FnName << '\n' ; // If there are no calls then you can't unwind. This may mean we can omit the // EH Frame, but some environments do not handle weak absolute symbols. If Added: llvm/trunk/test/CodeGen/X86/hidden-vis-5.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hidden-vis-5.ll?rev=86779&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/hidden-vis-5.ll (added) +++ llvm/trunk/test/CodeGen/X86/hidden-vis-5.ll Tue Nov 10 19:24:59 2009 @@ -0,0 +1,30 @@ +; RUN: llc < %s -march=x86 -relocation-model=pic -disable-fp-elim -unwind-tables | FileCheck %s +; + + at .str = private constant [12 x i8] c"hello world\00", align 1 ; <[12 x i8]*> [#uses=1] + +define hidden void @func() nounwind ssp { +entry: + %0 = call i32 @puts(i8* getelementptr inbounds ([12 x i8]* @.str, i64 0, i64 0)) nounwind ; [#uses=0] + br label %return + +return: ; preds = %entry + ret void +} + +declare i32 @puts(i8*) + +define hidden i32 @main() nounwind ssp { +entry: + %retval = alloca i32 ; [#uses=1] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + call void @func() nounwind + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; [#uses=1] + ret i32 %retval1 +} + +; CHECK: .private_extern _func.eh +; CHECK: .private_extern _main.eh From dpatel at apple.com Tue Nov 10 19:41:10 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 11 Nov 2009 01:41:10 -0000 Subject: [llvm-commits] [llvm] r86784 - /llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp Message-ID: <200911110141.nAB1fAwU012751@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 10 19:41:10 2009 New Revision: 86784 URL: http://llvm.org/viewvc/llvm-project?rev=86784&view=rev Log: XFAIL for now. Modified: llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp Modified: llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC%2B%2B/2006-11-06-StackTrace.cpp?rev=86784&r1=86783&r2=86784&view=diff ============================================================================== --- llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp (original) +++ llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp Tue Nov 10 19:41:10 2009 @@ -12,7 +12,7 @@ // Only works on ppc (but not apple-darwin9), x86 and x86_64. Should // generalize? -// XFAIL: alpha,arm,powerpc-apple-darwin9 +// XFAIL: * #include From isanbard at gmail.com Tue Nov 10 19:41:32 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 11 Nov 2009 01:41:32 -0000 Subject: [llvm-commits] [llvm] r86785 - /llvm/trunk/test/CodeGen/X86/hidden-vis-5.ll Message-ID: <200911110141.nAB1fWNh012772@zion.cs.uiuc.edu> Author: void Date: Tue Nov 10 19:41:32 2009 New Revision: 86785 URL: http://llvm.org/viewvc/llvm-project?rev=86785&view=rev Log: Fix test to work on every platform. Modified: llvm/trunk/test/CodeGen/X86/hidden-vis-5.ll Modified: llvm/trunk/test/CodeGen/X86/hidden-vis-5.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hidden-vis-5.ll?rev=86785&r1=86784&r2=86785&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/hidden-vis-5.ll (original) +++ llvm/trunk/test/CodeGen/X86/hidden-vis-5.ll Tue Nov 10 19:41:32 2009 @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -relocation-model=pic -disable-fp-elim -unwind-tables | FileCheck %s +; RUN: llc < %s -mtriple=i386-apple-darwin9 -relocation-model=pic -disable-fp-elim -unwind-tables | FileCheck %s ; @.str = private constant [12 x i8] c"hello world\00", align 1 ; <[12 x i8]*> [#uses=1] From isanbard at gmail.com Tue Nov 10 19:44:22 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 11 Nov 2009 01:44:22 -0000 Subject: [llvm-commits] [llvm] r86786 - /llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll Message-ID: <200911110144.nAB1iN2H012862@zion.cs.uiuc.edu> Author: void Date: Tue Nov 10 19:44:22 2009 New Revision: 86786 URL: http://llvm.org/viewvc/llvm-project?rev=86786&view=rev Log: Fix test to work on every platform. Modified: llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll Modified: llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll?rev=86786&r1=86785&r2=86786&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll Tue Nov 10 19:44:22 2009 @@ -1,6 +1,4 @@ -; RUN: llc < %s -march=ppc32 -disable-fp-elim | FileCheck %s -; XFAIL: * -; XTARGET: darwin +; RUN: llc < %s -mtriple=powerpc-apple-darwin8 -disable-fp-elim | FileCheck %s define i32 @_Z4funci(i32 %a) ssp { ; CHECK: mflr r0 From isanbard at gmail.com Tue Nov 10 19:44:41 2009 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 10 Nov 2009 17:44:41 -0800 Subject: [llvm-commits] [llvm] r86752 - /llvm/trunk/test/CodeGen/PowerPC/ppc-prologue.ll In-Reply-To: References: <200911102318.nAANIX7t006938@zion.cs.uiuc.edu> Message-ID: <3ECCAF66-AB93-44F5-BEA5-600AA9BE780D@gmail.com> Erm...because I forgot about the -mtriple. :-) Fixed. (I hope) -bw On Nov 10, 2009, at 3:30 PM, Anton Korobeynikov wrote: >> URL: http://llvm.org/viewvc/llvm-project?rev=86752&view=rev >> Log: >> Test this on Darwin only. > Why? > > -- > With best regards, Anton Korobeynikov > Faculty of Mathematics and Mechanics, Saint Petersburg State > University > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Tue Nov 10 20:08:33 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 02:08:33 -0000 Subject: [llvm-commits] [llvm] r86789 - in /llvm/trunk: include/llvm/Analysis/LazyValueInfo.h lib/Analysis/LazyValueInfo.cpp lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200911110208.nAB28X0E013556@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 20:08:33 2009 New Revision: 86789 URL: http://llvm.org/viewvc/llvm-project?rev=86789&view=rev Log: stub out some LazyValueInfo interfaces, and have JumpThreading start using them in a trivial way when -enable-jump-threading-lvi is passed. enable-jump-threading-lvi will be my playground for awhile. Modified: llvm/trunk/include/llvm/Analysis/LazyValueInfo.h llvm/trunk/lib/Analysis/LazyValueInfo.cpp llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/include/llvm/Analysis/LazyValueInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LazyValueInfo.h?rev=86789&r1=86788&r2=86789&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LazyValueInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/LazyValueInfo.h Tue Nov 10 20:08:33 2009 @@ -18,23 +18,44 @@ #include "llvm/Pass.h" namespace llvm { - + class Constant; + class TargetData; + class Value; + /// LazyValueInfo - This pass computes, caches, and vends lazy value constraint /// information. class LazyValueInfo : public FunctionPass { + class TargetData *TD; + void *PImpl; public: static char ID; - LazyValueInfo(); + LazyValueInfo() : FunctionPass(&ID), PImpl(0) {} + /// Tristate - This is used to return yes/no/dunno results. + enum Tristate { + Unknown = -1, No = 0, Yes = 1 + }; + + + // Public query interface. + + + /// isEqual - Determine whether the specified value is known to be equal or + /// not-equal to the specified constant at the end of the specified block. + Tristate isEqual(Value *V, Constant *C, BasicBlock *BB); + + /// getConstant - Determine whether the specified value is known to be a + /// constant at the end of the specified block. Return null if not. + Constant *getConstant(Value *V, BasicBlock *BB); + + + // Implementation boilerplate. + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } virtual void releaseMemory(); - - virtual bool runOnFunction(Function &F) { - // Fully lazy. - return false; - } + virtual bool runOnFunction(Function &F); }; } // end namespace llvm Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=86789&r1=86788&r2=86789&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Tue Nov 10 20:08:33 2009 @@ -13,6 +13,11 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/LazyValueInfo.h" +#include "llvm/Constants.h" +#include "llvm/Instructions.h" +#include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Target/TargetData.h" +#include "llvm/ADT/PointerIntPair.h" using namespace llvm; char LazyValueInfo::ID = 0; @@ -23,9 +28,119 @@ FunctionPass *createLazyValueInfoPass() { return new LazyValueInfo(); } } -LazyValueInfo::LazyValueInfo() : FunctionPass(&ID) { + +//===----------------------------------------------------------------------===// +// LVILatticeVal +//===----------------------------------------------------------------------===// + +/// LVILatticeVal - This is the information tracked by LazyValueInfo for each +/// value. +/// +/// FIXME: This is basically just for bringup, this can be made a lot more rich +/// in the future. +/// +namespace { +class LVILatticeVal { + enum LatticeValueTy { + /// undefined - This LLVM Value has no known value yet. + undefined, + /// constant - This LLVM Value has a specific constant value. + constant, + /// overdefined - This instruction is not known to be constant, and we know + /// it has a value. + overdefined + }; + + /// Val: This stores the current lattice value along with the Constant* for + /// the constant if this is a 'constant' value. + PointerIntPair Val; + +public: + LVILatticeVal() : Val(0, undefined) {} + + bool isUndefined() const { return Val.getInt() == undefined; } + bool isConstant() const { return Val.getInt() == constant; } + bool isOverdefined() const { return Val.getInt() == overdefined; } + + Constant *getConstant() const { + assert(isConstant() && "Cannot get the constant of a non-constant!"); + return Val.getPointer(); + } + + /// getConstantInt - If this is a constant with a ConstantInt value, return it + /// otherwise return null. + ConstantInt *getConstantInt() const { + if (isConstant()) + return dyn_cast(getConstant()); + return 0; + } + + /// markOverdefined - Return true if this is a change in status. + bool markOverdefined() { + if (isOverdefined()) + return false; + Val.setInt(overdefined); + return true; + } + + /// markConstant - Return true if this is a change in status. + bool markConstant(Constant *V) { + if (isConstant()) { + assert(getConstant() == V && "Marking constant with different value"); + return false; + } + + assert(isUndefined()); + Val.setInt(constant); + assert(V && "Marking constant with NULL"); + Val.setPointer(V); + } + +}; + +} // end anonymous namespace. + + +//===----------------------------------------------------------------------===// +// LazyValueInfo Impl +//===----------------------------------------------------------------------===// + +bool LazyValueInfo::runOnFunction(Function &F) { + TD = getAnalysisIfAvailable(); + // Fully lazy. + return false; } void LazyValueInfo::releaseMemory() { + // No caching yet. +} + + +/// isEqual - Determine whether the specified value is known to be equal or +/// not-equal to the specified constant at the end of the specified block. +LazyValueInfo::Tristate +LazyValueInfo::isEqual(Value *V, Constant *C, BasicBlock *BB) { + // If already a constant, we can use constant folding. + if (Constant *VC = dyn_cast(V)) { + // Ignore FP for now. TODO, consider what form of equality we want. + if (C->getType()->isFPOrFPVector()) + return Unknown; + + Constant *Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_EQ, VC,C,TD); + if (ConstantInt *ResCI = dyn_cast(Res)) + return ResCI->isZero() ? No : Yes; + } + // Not a very good implementation. + return Unknown; } + +Constant *LazyValueInfo::getConstant(Value *V, BasicBlock *BB) { + // If already a constant, return it. + if (Constant *VC = dyn_cast(V)) + return VC; + + // Not a very good implementation. + return 0; +} + Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86789&r1=86788&r2=86789&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Tue Nov 10 20:08:33 2009 @@ -17,6 +17,7 @@ #include "llvm/LLVMContext.h" #include "llvm/Pass.h" #include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Analysis/LazyValueInfo.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/SSAUpdater.h" @@ -40,6 +41,12 @@ cl::desc("Max block size to duplicate for jump threading"), cl::init(6), cl::Hidden); +// Turn on use of LazyValueInfo. +static cl::opt +EnableLVI("enable-jump-threading-lvi", cl::ReallyHidden); + + + namespace { /// This pass performs 'jump threading', which looks at blocks that have /// multiple predecessors and multiple successors. If one or more of the @@ -59,6 +66,7 @@ /// class JumpThreading : public FunctionPass { TargetData *TD; + LazyValueInfo *LVI; #ifdef NDEBUG SmallPtrSet LoopHeaders; #else @@ -69,8 +77,13 @@ JumpThreading() : FunctionPass(&ID) {} bool runOnFunction(Function &F); - void FindLoopHeaders(Function &F); + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + if (EnableLVI) + AU.addRequired(); + } + + void FindLoopHeaders(Function &F); bool ProcessBlock(BasicBlock *BB); bool ThreadEdge(BasicBlock *BB, const SmallVectorImpl &PredBBs, BasicBlock *SuccBB); @@ -106,6 +119,7 @@ bool JumpThreading::runOnFunction(Function &F) { DEBUG(errs() << "Jump threading on function '" << F.getName() << "'\n"); TD = getAnalysisIfAvailable(); + LVI = EnableLVI ? &getAnalysis() : 0; FindLoopHeaders(F); @@ -235,31 +249,48 @@ /// predecessors. If so, return the known list of value and pred BB in the /// result vector. If a value is known to be undef, it is returned as null. /// -/// The BB basic block is known to start with a PHI node. -/// /// This returns true if there were any known values. /// -/// -/// TODO: Per PR2563, we could infer value range information about a predecessor -/// based on its terminator. bool JumpThreading:: ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ - PHINode *TheFirstPHI = cast(BB->begin()); - // If V is a constantint, then it is known in all predecessors. if (isa(V) || isa(V)) { ConstantInt *CI = dyn_cast(V); - Result.resize(TheFirstPHI->getNumIncomingValues()); - for (unsigned i = 0, e = Result.size(); i != e; ++i) - Result[i] = std::make_pair(CI, TheFirstPHI->getIncomingBlock(i)); + + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) + Result.push_back(std::make_pair(CI, *PI)); return true; } // If V is a non-instruction value, or an instruction in a different block, // then it can't be derived from a PHI. Instruction *I = dyn_cast(V); - if (I == 0 || I->getParent() != BB) + if (I == 0 || I->getParent() != BB) { + + // Okay, if this is a live-in value, see if it has a known value at the end + // of any of our predecessors. + // + // FIXME: This should be an edge property, not a block end property. + /// TODO: Per PR2563, we could infer value range information about a + /// predecessor based on its terminator. + // + if (LVI) { + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { + // If the value is known by LazyValueInfo to be a constant in a + // predecessor, use that information to try to thread this block. + Constant *PredCst = LVI->getConstant(V, *PI); + if (PredCst == 0 || + (!isa(PredCst) && !isa(PredCst))) + continue; + + Result.push_back(std::make_pair(dyn_cast(PredCst), *PI)); + } + + return !Result.empty(); + } + return false; + } /// If I is a PHI node, then we know the incoming values for any constants. if (PHINode *PN = dyn_cast(I)) { @@ -517,12 +548,8 @@ // a PHI node in the current block. If we can prove that any predecessors // compute a predictable value based on a PHI node, thread those predecessors. // - // We only bother doing this if the current block has a PHI node and if the - // conditional instruction lives in the current block. If either condition - // fails, this won't be a computable value anyway. - if (CondInst->getParent() == BB && isa(BB->front())) - if (ProcessThreadableEdges(CondInst, BB)) - return true; + if (ProcessThreadableEdges(CondInst, BB)) + return true; // TODO: If we have: "br (X > 0)" and we have a predecessor where we know From vargaz at gmail.com Tue Nov 10 20:36:12 2009 From: vargaz at gmail.com (Zoltan Varga) Date: Wed, 11 Nov 2009 03:36:12 +0100 Subject: [llvm-commits] [PATH] Implement generation of dwarf unwind info on ARM ELF In-Reply-To: <295e750a0911082339p3428e9m3529e903f0bccf4e@mail.gmail.com> References: <295e750a0911082339p3428e9m3529e903f0bccf4e@mail.gmail.com> Message-ID: <295e750a0911101836g1855f75dp149882d3c86589e7@mail.gmail.com> Hi, Since writing this, I realized that ARM doesn't use .eh_frame for unwinding. So ignore this patch for now. Zoltan On Mon, Nov 9, 2009 at 8:39 AM, Zoltan Varga wrote: > Hi, > > The attached patch implements the generation of DWARF unwind info on ARM. > It is currently only enabled on ELF platforms when > -unwind-tables is passed to llc. > > I tested with manually by examining the output of objdump -W. > > Please review and commit if it looks ok. > > Zoltan > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091111/bb722dc4/attachment.html From grosbach at apple.com Tue Nov 10 20:47:19 2009 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 11 Nov 2009 02:47:19 -0000 Subject: [llvm-commits] [llvm] r86791 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Message-ID: <200911110247.nAB2lJjM014802@zion.cs.uiuc.edu> Author: grosbach Date: Tue Nov 10 20:47:19 2009 New Revision: 86791 URL: http://llvm.org/viewvc/llvm-project?rev=86791&view=rev Log: The TBB and TBH instructions for Thumb2 are really handy for jump tables, but can only branch forward. To best take advantage of them, we'd like to adjust the basic blocks around a bit when reasonable. This patch puts basics in place to do that, with a super-simple algorithm for backwards jump table targets that creates a new branch after the jump table which branches backwards. Real heuristics for reordering blocks or other modifications rather than inserting branches will follow. Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=86791&r1=86790&r2=86791&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Tue Nov 10 20:47:19 2009 @@ -31,6 +31,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Support/CommandLine.h" #include using namespace llvm; @@ -42,6 +43,12 @@ STATISTIC(NumT2CPShrunk, "Number of Thumb2 constantpool instructions shrunk"); STATISTIC(NumT2BrShrunk, "Number of Thumb2 immediate branches shrunk"); STATISTIC(NumCBZ, "Number of CBZ / CBNZ formed"); +STATISTIC(NumJTMoved, "Number of jump table destination blocks moved"); + + +static cl::opt +AdjustJumpTableBlocks("arm-adjust-jump-tables", cl::Hidden, cl::init(false), + cl::desc("Adjust basic block layout to better use TB[BH]")); namespace { /// ARMConstantIslands - Due to limited PC-relative displacements, ARM @@ -202,6 +209,8 @@ bool OptimizeThumb2Instructions(MachineFunction &MF); bool OptimizeThumb2Branches(MachineFunction &MF); bool OptimizeThumb2JumpTables(MachineFunction &MF); + MachineBasicBlock *AdjustJTTargetBlockForward(MachineBasicBlock *BB, + MachineBasicBlock *JTBB); unsigned GetOffsetOf(MachineInstr *MI) const; void dumpBBs(); @@ -1560,7 +1569,7 @@ // FIXME: After the tables are shrunk, can we get rid some of the // constantpool tables? - const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); + MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); const std::vector &JT = MJTI->getJumpTables(); for (unsigned i = 0, e = T2JumpTables.size(); i != e; ++i) { MachineInstr *MI = T2JumpTables[i]; @@ -1571,10 +1580,33 @@ unsigned JTI = JTOP.getIndex(); assert(JTI < JT.size()); - bool ByteOk = true; - bool HalfWordOk = true; + // We prefer if target blocks for the jump table come after the jump + // instruction so we can use TB[BH]. Loop through the target blocks + // and try to adjust them such that that's true. unsigned JTOffset = GetOffsetOf(MI) + 4; const std::vector &JTBBs = JT[JTI].MBBs; + if (AdjustJumpTableBlocks) { + for (unsigned j = 0, ee = JTBBs.size(); j != ee; ++j) { + MachineBasicBlock *MBB = JTBBs[j]; + unsigned DstOffset = BBOffsets[MBB->getNumber()]; + + if (DstOffset < JTOffset) { + // The destination precedes the switch. Try to move the block forward + // so we have a positive offset. + MachineBasicBlock *NewBB = + AdjustJTTargetBlockForward(MBB, MI->getParent()); + if (NewBB) { + MJTI->ReplaceMBBInJumpTables(JTBBs[j], NewBB); + JTOffset = GetOffsetOf(MI) + 4; + DstOffset = BBOffsets[MBB->getNumber()]; + } + } + } + } + + bool ByteOk = true; + bool HalfWordOk = true; + JTOffset = GetOffsetOf(MI) + 4; for (unsigned j = 0, ee = JTBBs.size(); j != ee; ++j) { MachineBasicBlock *MBB = JTBBs[j]; unsigned DstOffset = BBOffsets[MBB->getNumber()]; @@ -1660,3 +1692,64 @@ return MadeChange; } + +MachineBasicBlock *ARMConstantIslands:: +AdjustJTTargetBlockForward(MachineBasicBlock *BB, MachineBasicBlock *JTBB) +{ + MachineFunction &MF = *BB->getParent(); + + // FIXME: For now, instead of moving the block, we'll create a new block + // immediate following the jump that's an unconditional branch to the + // actual target. This is obviously not what we want for a real solution, + // but it's useful for proof of concept, and it may be a useful fallback + // later for cases where we otherwise can't move a block. + + // Create a new MBB for the code after the jump BB. + MachineBasicBlock *NewBB = + MF.CreateMachineBasicBlock(JTBB->getBasicBlock()); + MachineFunction::iterator MBBI = JTBB; ++MBBI; + MF.insert(MBBI, NewBB); + + // Add an unconditional branch from NewBB to BB. + // There doesn't seem to be meaningful DebugInfo available; this doesn't + // correspond directly to anything in the source. + assert (isThumb2 && "Adjusting for TB[BH] but not in Thumb2?"); + BuildMI(NewBB, DebugLoc::getUnknownLoc(), TII->get(ARM::t2B)).addMBB(BB); + + // Update the CFG. + NewBB->addSuccessor(BB); + JTBB->removeSuccessor(BB); + JTBB->addSuccessor(NewBB); + + // Update internal data structures to account for the newly inserted MBB. + // This is almost the same as UpdateForInsertedWaterBlock, except that + // the Water goes after OrigBB, not NewBB. + MF.RenumberBlocks(NewBB); + + // Insert a size into BBSizes to align it properly with the (newly + // renumbered) block numbers. + BBSizes.insert(BBSizes.begin()+NewBB->getNumber(), 0); + + // Likewise for BBOffsets. + BBOffsets.insert(BBOffsets.begin()+NewBB->getNumber(), 0); + + // Figure out how large the first NewMBB is. + unsigned NewBBSize = 0; + for (MachineBasicBlock::iterator I = NewBB->begin(), E = NewBB->end(); + I != E; ++I) + NewBBSize += TII->GetInstSizeInBytes(I); + + unsigned NewBBI = NewBB->getNumber(); + unsigned JTBBI = JTBB->getNumber(); + // Set the size of NewBB in BBSizes. + BBSizes[NewBBI] = NewBBSize; + + // ...and adjust BBOffsets for NewBB accordingly. + BBOffsets[NewBBI] = BBOffsets[JTBBI] + BBSizes[JTBBI]; + + // All BBOffsets following these blocks must be modified. + AdjustBBOffsetsAfter(NewBB, 4); + + ++NumJTMoved; + return NewBB; +} From espindola at google.com Tue Nov 10 21:05:34 2009 From: espindola at google.com (Rafael Espindola) Date: Tue, 10 Nov 2009 22:05:34 -0500 Subject: [llvm-commits] [patch] Remove dead code Message-ID: <38a0d8450911101905g34b9b885k5b19afbbe0aff0c7@mail.gmail.com> Can simple patches as the attached one be reviewed after being committed? Cheers, -- Rafael ?vila de Esp?ndola -------------- next part -------------- A non-text attachment was scrubbed... Name: dead.patch Type: text/x-diff Size: 632 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091110/d8b40aac/attachment.bin From daniel at zuster.org Tue Nov 10 21:09:50 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 11 Nov 2009 03:09:50 -0000 Subject: [llvm-commits] [llvm] r86794 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Message-ID: <200911110309.nAB39oHf015509@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 10 21:09:50 2009 New Revision: 86794 URL: http://llvm.org/viewvc/llvm-project?rev=86794&view=rev Log: Fix -Asserts warning. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=86794&r1=86793&r2=86794&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Nov 10 21:09:50 2009 @@ -1565,6 +1565,7 @@ DIScope DS(Scope->getScopeNode()); DISubprogram InlinedSP = getDISubprogram(DS.getNode()); DIE *&OriginSPDIE = ModuleCU->getDieMapSlotFor(InlinedSP.getNode()); + (void) OriginSPDIE; assert (OriginSPDIE && "Unable to find Origin DIE for the SP!"); DIE *AbsDIE = DV->getAbstractVariable()->getDIE(); assert (AbsDIE && "Unable to find Origin DIE for the Variable!"); From daniel at zuster.org Tue Nov 10 21:10:03 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 11 Nov 2009 03:10:03 -0000 Subject: [llvm-commits] [llvm] r86795 - /llvm/trunk/test/DebugInfo/2009-11-10-CurrentFn.ll Message-ID: <200911110310.nAB3A3Yt015532@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 10 21:10:03 2009 New Revision: 86795 URL: http://llvm.org/viewvc/llvm-project?rev=86795&view=rev Log: Add missing run line. Devang, please check. Modified: llvm/trunk/test/DebugInfo/2009-11-10-CurrentFn.ll Modified: llvm/trunk/test/DebugInfo/2009-11-10-CurrentFn.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2009-11-10-CurrentFn.ll?rev=86795&r1=86794&r2=86795&view=diff ============================================================================== --- llvm/trunk/test/DebugInfo/2009-11-10-CurrentFn.ll (original) +++ llvm/trunk/test/DebugInfo/2009-11-10-CurrentFn.ll Tue Nov 10 21:10:03 2009 @@ -1,3 +1,4 @@ +; RUN: llc < %s -o /dev/null declare void @foo() From deeppatel1987 at gmail.com Tue Nov 10 21:23:47 2009 From: deeppatel1987 at gmail.com (Sandeep Patel) Date: Wed, 11 Nov 2009 03:23:47 -0000 Subject: [llvm-commits] [llvm] r86797 - in /llvm/trunk: lib/Support/CommandLine.cpp utils/TableGen/SubtargetEmitter.cpp Message-ID: <200911110323.nAB3NlpL016081@zion.cs.uiuc.edu> Author: sandeep Date: Tue Nov 10 21:23:46 2009 New Revision: 86797 URL: http://llvm.org/viewvc/llvm-project?rev=86797&view=rev Log: Show command-line args and features passed into backend in debug output. Approved by Evan Cheng. Modified: llvm/trunk/lib/Support/CommandLine.cpp llvm/trunk/utils/TableGen/SubtargetEmitter.cpp Modified: llvm/trunk/lib/Support/CommandLine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CommandLine.cpp?rev=86797&r1=86796&r2=86797&view=diff ============================================================================== --- llvm/trunk/lib/Support/CommandLine.cpp (original) +++ llvm/trunk/lib/Support/CommandLine.cpp Tue Nov 10 21:23:46 2009 @@ -17,6 +17,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/ManagedStatic.h" @@ -765,6 +766,11 @@ free(*i); } + DEBUG(errs() << "\nArgs: "; + for (int i = 0; i < argc; ++i) + errs() << argv[i] << ' '; + ); + // If we had an error processing our arguments, don't let the program execute if (ErrorParsing) exit(1); } Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetEmitter.cpp?rev=86797&r1=86796&r2=86797&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp Tue Nov 10 21:23:46 2009 @@ -519,6 +519,8 @@ OS << Target; OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n" << " const std::string &CPU) {\n" + << " DEBUG(errs() << \"\\nFeatures:\" << FS);\n" + << " DEBUG(errs() << \"\\nCPU:\" << CPU);\n" << " SubtargetFeatures Features(FS);\n" << " Features.setCPUIfNone(CPU);\n" << " uint32_t Bits = Features.getBits(SubTypeKV, SubTypeKVSize,\n" @@ -558,6 +560,8 @@ EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); + OS << "#include \"llvm/Support/Debug.h\"\n"; + OS << "#include \"llvm/Support/raw_ostream.h\"\n"; OS << "#include \"llvm/Target/SubtargetFeature.h\"\n"; OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n"; From clattner at apple.com Tue Nov 10 21:56:02 2009 From: clattner at apple.com (Chris Lattner) Date: Tue, 10 Nov 2009 19:56:02 -0800 Subject: [llvm-commits] [patch] Remove dead code In-Reply-To: <38a0d8450911101905g34b9b885k5b19afbbe0aff0c7@mail.gmail.com> References: <38a0d8450911101905g34b9b885k5b19afbbe0aff0c7@mail.gmail.com> Message-ID: On Nov 10, 2009, at 7:05 PM, Rafael Espindola wrote: > Can simple patches as the attached one be reviewed after being > committed? Absolutely, go for it. -Chris > > Cheers, > -- > Rafael ?vila de Esp?ndola > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From rafael.espindola at gmail.com Tue Nov 10 22:10:34 2009 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 11 Nov 2009 04:10:34 -0000 Subject: [llvm-commits] [llvm] r86802 - /llvm/trunk/lib/CompilerDriver/Tool.cpp Message-ID: <200911110410.nAB4AZq2017981@zion.cs.uiuc.edu> Author: rafael Date: Tue Nov 10 22:10:24 2009 New Revision: 86802 URL: http://llvm.org/viewvc/llvm-project?rev=86802&view=rev Log: Remove dead code. Modified: llvm/trunk/lib/CompilerDriver/Tool.cpp Modified: llvm/trunk/lib/CompilerDriver/Tool.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CompilerDriver/Tool.cpp?rev=86802&r1=86801&r2=86802&view=diff ============================================================================== --- llvm/trunk/lib/CompilerDriver/Tool.cpp (original) +++ llvm/trunk/lib/CompilerDriver/Tool.cpp Tue Nov 10 22:10:24 2009 @@ -20,11 +20,6 @@ using namespace llvm; using namespace llvmc; -// SplitString is used by derived Tool classes. -typedef void (*SplitStringFunPtr)(const std::string&, - std::vector&, const char*); -SplitStringFunPtr ForceLinkageSplitString = &llvm::SplitString; - namespace { sys::Path MakeTempFile(const sys::Path& TempDir, const std::string& BaseName, const std::string& Suffix) { From daniel at zuster.org Tue Nov 10 23:19:18 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 11 Nov 2009 05:19:18 -0000 Subject: [llvm-commits] [llvm] r86803 - /llvm/trunk/include/llvm/ADT/StringRef.h Message-ID: <200911110519.nAB5JJq1020571@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 10 23:19:11 2009 New Revision: 86803 URL: http://llvm.org/viewvc/llvm-project?rev=86803&view=rev Log: Add StringRef::split(StringRef), to complement StringRef::split(char). Modified: llvm/trunk/include/llvm/ADT/StringRef.h Modified: llvm/trunk/include/llvm/ADT/StringRef.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringRef.h?rev=86803&r1=86802&r2=86803&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/StringRef.h (original) +++ llvm/trunk/include/llvm/ADT/StringRef.h Tue Nov 10 23:19:11 2009 @@ -289,6 +289,23 @@ return std::make_pair(slice(0, Idx), slice(Idx+1, npos)); } + /// split - Split into two substrings around the first occurence of a + /// separator string. + /// + /// If \arg Separator is in the string, then the result is a pair (LHS, RHS) + /// such that (*this == LHS + Separator + RHS) is true and RHS is + /// maximal. If \arg Separator is not in the string, then the result is a + /// pair (LHS, RHS) where (*this == LHS) and (RHS == ""). + /// + /// \param Separator - The string to split on. + /// \return - The split substrings. + std::pair split(StringRef Separator) const { + size_t Idx = find(Separator); + if (Idx == npos) + return std::make_pair(*this, StringRef()); + return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos)); + } + /// rsplit - Split into two substrings around the last occurence of a /// separator character. /// From sabre at nondot.org Tue Nov 10 23:25:21 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 05:25:21 -0000 Subject: [llvm-commits] [llvm] r86804 - /llvm/trunk/test/Transforms/CondProp/ Message-ID: <200911110525.nAB5PLQ5020859@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 23:25:16 2009 New Revision: 86804 URL: http://llvm.org/viewvc/llvm-project?rev=86804&view=rev Log: remove condprop testcases. Removed: llvm/trunk/test/Transforms/CondProp/ From sabre at nondot.org Tue Nov 10 23:26:05 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 10 Nov 2009 23:26:05 -0600 Subject: [llvm-commits] CVS: llvm-www/OpenProjects.html Message-ID: <200911110526.nAB5Q5dK020885@zion.cs.uiuc.edu> Changes in directory llvm-www: OpenProjects.html updated: 1.54 -> 1.55 --- Log message: this is done, thanks to Daveed for pointing this out. --- Diffs of the changes: (+1 -2) OpenProjects.html | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm-www/OpenProjects.html diff -u llvm-www/OpenProjects.html:1.54 llvm-www/OpenProjects.html:1.55 --- llvm-www/OpenProjects.html:1.54 Wed Oct 28 23:29:39 2009 +++ llvm-www/OpenProjects.html Tue Nov 10 23:24:12 2009 @@ -240,7 +240,6 @@
  • Improvements for Debug Information Generation
  • EH support for non-call exceptions
  • -
  • Support for multiple return values
  • Add support for representing Type Based Alias Analysis (TBAA) in the LLVM IR.
  • Many ideas for feature requests are stored in LLVM bugzilla. Just LLVM Compiler Infrastructure
    - Last modified: $Date: 2009/10/29 04:29:39 $ + Last modified: $Date: 2009/11/11 05:24:12 $ From jyasskin at google.com Tue Nov 10 23:30:03 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Wed, 11 Nov 2009 05:30:03 -0000 Subject: [llvm-commits] [llvm] r86807 - /llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Message-ID: <200911110530.nAB5U3mk021189@zion.cs.uiuc.edu> Author: jyasskin Date: Tue Nov 10 23:30:02 2009 New Revision: 86807 URL: http://llvm.org/viewvc/llvm-project?rev=86807&view=rev Log: Fix JITTest.ModuleDeletion in -Asserts mode (which turns off JITEmitDebugInfo by default). Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=86807&r1=86806&r2=86807&view=diff ============================================================================== --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original) +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Tue Nov 10 23:30:02 2009 @@ -434,10 +434,16 @@ RJMM->deallocateFunctionBodyCalls.size()); SmallPtrSet ExceptionTablesDeallocated; + unsigned NumTablesDeallocated = 0; for (unsigned i = 0, e = RJMM->deallocateExceptionTableCalls.size(); i != e; ++i) { ExceptionTablesDeallocated.insert( RJMM->deallocateExceptionTableCalls[i].ET); + if (RJMM->deallocateExceptionTableCalls[i].ET != NULL) { + // If JITEmitDebugInfo is off, we'll "deallocate" NULL, which doesn't + // appear in startExceptionTableCalls. + NumTablesDeallocated++; + } } for (unsigned i = 0, e = RJMM->startExceptionTableCalls.size(); i != e; ++i) { EXPECT_TRUE(ExceptionTablesDeallocated.count( @@ -446,7 +452,7 @@ << RJMM->startExceptionTableCalls[i].F_dump; } EXPECT_EQ(RJMM->startExceptionTableCalls.size(), - RJMM->deallocateExceptionTableCalls.size()); + NumTablesDeallocated); } // This code is copied from JITEventListenerTest, but it only runs once for all From sabre at nondot.org Tue Nov 10 23:56:36 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 05:56:36 -0000 Subject: [llvm-commits] [llvm] r86810 - in /llvm/trunk: include/llvm-c/Transforms/Scalar.h include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/CMakeLists.txt lib/Transforms/Scalar/CondPropagate.cpp lib/Transforms/Scalar/Scalar.cpp Message-ID: <200911110556.nAB5uacl021976@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 10 23:56:35 2009 New Revision: 86810 URL: http://llvm.org/viewvc/llvm-project?rev=86810&view=rev Log: remove the now dead condprop pass, PR3906. Removed: llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp Modified: llvm/trunk/include/llvm-c/Transforms/Scalar.h llvm/trunk/include/llvm/LinkAllPasses.h llvm/trunk/include/llvm/Transforms/Scalar.h llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Modified: llvm/trunk/include/llvm-c/Transforms/Scalar.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Transforms/Scalar.h?rev=86810&r1=86809&r2=86810&view=diff ============================================================================== --- llvm/trunk/include/llvm-c/Transforms/Scalar.h (original) +++ llvm/trunk/include/llvm-c/Transforms/Scalar.h Tue Nov 10 23:56:35 2009 @@ -31,9 +31,6 @@ /** See llvm::createCFGSimplificationPass function. */ void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM); -/** See llvm::createCondPropagationPass function. */ -void LLVMAddCondPropagationPass(LLVMPassManagerRef PM); - /** See llvm::createDeadStoreEliminationPass function. */ void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM); Modified: llvm/trunk/include/llvm/LinkAllPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=86810&r1=86809&r2=86810&view=diff ============================================================================== --- llvm/trunk/include/llvm/LinkAllPasses.h (original) +++ llvm/trunk/include/llvm/LinkAllPasses.h Tue Nov 10 23:56:35 2009 @@ -120,7 +120,6 @@ (void) llvm::createTailDuplicationPass(); (void) llvm::createJumpThreadingPass(); (void) llvm::createUnifyFunctionExitNodesPass(); - (void) llvm::createCondPropagationPass(); (void) llvm::createNullProfilerRSPass(); (void) llvm::createRSProfilingPass(); (void) llvm::createInstCountPass(); Modified: llvm/trunk/include/llvm/Transforms/Scalar.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=86810&r1=86809&r2=86810&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Scalar.h (original) +++ llvm/trunk/include/llvm/Transforms/Scalar.h Tue Nov 10 23:56:35 2009 @@ -171,14 +171,6 @@ //===----------------------------------------------------------------------===// // -// CondPropagationPass - This pass propagates information about conditional -// expressions through the program, allowing it to eliminate conditional -// branches in some cases. -// -FunctionPass *createCondPropagationPass(); - -//===----------------------------------------------------------------------===// -// // TailDuplication - Eliminate unconditional branches through controlled code // duplication, creating simpler CFG structures. // Modified: llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt?rev=86810&r1=86809&r2=86810&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt (original) +++ llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Tue Nov 10 23:56:35 2009 @@ -3,7 +3,6 @@ ADCE.cpp BasicBlockPlacement.cpp CodeGenPrepare.cpp - CondPropagate.cpp ConstantProp.cpp DCE.cpp DeadStoreElimination.cpp Removed: llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp?rev=86809&view=auto ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp (removed) @@ -1,289 +0,0 @@ -//===-- CondPropagate.cpp - Propagate Conditional Expressions -------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This pass propagates information about conditional expressions through the -// program, allowing it to eliminate conditional branches in some cases. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "condprop" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Instructions.h" -#include "llvm/IntrinsicInst.h" -#include "llvm/Pass.h" -#include "llvm/Type.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/Transforms/Utils/Local.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/SmallVector.h" -using namespace llvm; - -STATISTIC(NumBrThread, "Number of CFG edges threaded through branches"); -STATISTIC(NumSwThread, "Number of CFG edges threaded through switches"); - -namespace { - struct CondProp : public FunctionPass { - static char ID; // Pass identification, replacement for typeid - CondProp() : FunctionPass(&ID) {} - - virtual bool runOnFunction(Function &F); - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredID(BreakCriticalEdgesID); - //AU.addRequired(); - } - - private: - bool MadeChange; - SmallVector DeadBlocks; - void SimplifyBlock(BasicBlock *BB); - void SimplifyPredecessors(BranchInst *BI); - void SimplifyPredecessors(SwitchInst *SI); - void RevectorBlockTo(BasicBlock *FromBB, BasicBlock *ToBB); - bool RevectorBlockTo(BasicBlock *FromBB, Value *Cond, BranchInst *BI); - }; -} - -char CondProp::ID = 0; -static RegisterPass X("condprop", "Conditional Propagation"); - -FunctionPass *llvm::createCondPropagationPass() { - return new CondProp(); -} - -bool CondProp::runOnFunction(Function &F) { - bool EverMadeChange = false; - DeadBlocks.clear(); - - // While we are simplifying blocks, keep iterating. - do { - MadeChange = false; - for (Function::iterator BB = F.begin(), E = F.end(); BB != E;) - SimplifyBlock(BB++); - EverMadeChange = EverMadeChange || MadeChange; - } while (MadeChange); - - if (EverMadeChange) { - while (!DeadBlocks.empty()) { - BasicBlock *BB = DeadBlocks.back(); DeadBlocks.pop_back(); - DeleteDeadBlock(BB); - } - } - return EverMadeChange; -} - -void CondProp::SimplifyBlock(BasicBlock *BB) { - if (BranchInst *BI = dyn_cast(BB->getTerminator())) { - // If this is a conditional branch based on a phi node that is defined in - // this block, see if we can simplify predecessors of this block. - if (BI->isConditional() && isa(BI->getCondition()) && - cast(BI->getCondition())->getParent() == BB) - SimplifyPredecessors(BI); - - } else if (SwitchInst *SI = dyn_cast(BB->getTerminator())) { - if (isa(SI->getCondition()) && - cast(SI->getCondition())->getParent() == BB) - SimplifyPredecessors(SI); - } - - // If possible, simplify the terminator of this block. - if (ConstantFoldTerminator(BB)) - MadeChange = true; - - // If this block ends with an unconditional branch and the only successor has - // only this block as a predecessor, merge the two blocks together. - if (BranchInst *BI = dyn_cast(BB->getTerminator())) - if (BI->isUnconditional() && BI->getSuccessor(0)->getSinglePredecessor() && - BB != BI->getSuccessor(0)) { - BasicBlock *Succ = BI->getSuccessor(0); - - // If Succ has any PHI nodes, they are all single-entry PHI's. Eliminate - // them. - FoldSingleEntryPHINodes(Succ); - - // Remove BI. - BI->eraseFromParent(); - - // Move over all of the instructions. - BB->getInstList().splice(BB->end(), Succ->getInstList()); - - // Any phi nodes that had entries for Succ now have entries from BB. - Succ->replaceAllUsesWith(BB); - - // Succ is now dead, but we cannot delete it without potentially - // invalidating iterators elsewhere. Just insert an unreachable - // instruction in it and delete this block later on. - new UnreachableInst(BB->getContext(), Succ); - DeadBlocks.push_back(Succ); - MadeChange = true; - } -} - -// SimplifyPredecessors(branches) - We know that BI is a conditional branch -// based on a PHI node defined in this block. If the phi node contains constant -// operands, then the blocks corresponding to those operands can be modified to -// jump directly to the destination instead of going through this block. -void CondProp::SimplifyPredecessors(BranchInst *BI) { - // TODO: We currently only handle the most trival case, where the PHI node has - // one use (the branch), and is the only instruction besides the branch and dbg - // intrinsics in the block. - PHINode *PN = cast(BI->getCondition()); - - if (PN->getNumIncomingValues() == 1) { - // Eliminate single-entry PHI nodes. - FoldSingleEntryPHINodes(PN->getParent()); - return; - } - - - if (!PN->hasOneUse()) return; - - BasicBlock *BB = BI->getParent(); - if (&*BB->begin() != PN) - return; - BasicBlock::iterator BBI = BB->begin(); - BasicBlock::iterator BBE = BB->end(); - while (BBI != BBE && isa(++BBI)) /* empty */; - if (&*BBI != BI) - return; - - // Ok, we have this really simple case, walk the PHI operands, looking for - // constants. Walk from the end to remove operands from the end when - // possible, and to avoid invalidating "i". - for (unsigned i = PN->getNumIncomingValues(); i != 0; --i) { - Value *InVal = PN->getIncomingValue(i-1); - if (!RevectorBlockTo(PN->getIncomingBlock(i-1), InVal, BI)) - continue; - - ++NumBrThread; - - // If there were two predecessors before this simplification, or if the - // PHI node contained all the same value except for the one we just - // substituted, the PHI node may be deleted. Don't iterate through it the - // last time. - if (BI->getCondition() != PN) return; - } -} - -// SimplifyPredecessors(switch) - We know that SI is switch based on a PHI node -// defined in this block. If the phi node contains constant operands, then the -// blocks corresponding to those operands can be modified to jump directly to -// the destination instead of going through this block. -void CondProp::SimplifyPredecessors(SwitchInst *SI) { - // TODO: We currently only handle the most trival case, where the PHI node has - // one use (the branch), and is the only instruction besides the branch and - // dbg intrinsics in the block. - PHINode *PN = cast(SI->getCondition()); - if (!PN->hasOneUse()) return; - - BasicBlock *BB = SI->getParent(); - if (&*BB->begin() != PN) - return; - BasicBlock::iterator BBI = BB->begin(); - BasicBlock::iterator BBE = BB->end(); - while (BBI != BBE && isa(++BBI)) /* empty */; - if (&*BBI != SI) - return; - - // Ok, we have this really simple case, walk the PHI operands, looking for - // constants. Walk from the end to remove operands from the end when - // possible, and to avoid invalidating "i". - for (unsigned i = PN->getNumIncomingValues(); i != 0; --i) - if (ConstantInt *CI = dyn_cast(PN->getIncomingValue(i-1))) { - BasicBlock *PredBB = PN->getIncomingBlock(i-1); - if (isa(PredBB->getTerminator())) { - // If we have a constant, forward the edge from its current to its - // ultimate destination. - unsigned DestCase = SI->findCaseValue(CI); - RevectorBlockTo(PredBB, SI->getSuccessor(DestCase)); - ++NumSwThread; - - // If there were two predecessors before this simplification, or if the - // PHI node contained all the same value except for the one we just - // substituted, the PHI node may be deleted. Don't iterate through it the - // last time. - if (SI->getCondition() != PN) return; - } - } -} - - -// RevectorBlockTo - Revector the unconditional branch at the end of FromBB to -// the ToBB block, which is one of the successors of its current successor. -void CondProp::RevectorBlockTo(BasicBlock *FromBB, BasicBlock *ToBB) { - BranchInst *FromBr = cast(FromBB->getTerminator()); - assert(FromBr->isUnconditional() && "FromBB should end with uncond br!"); - - // Get the old block we are threading through. - BasicBlock *OldSucc = FromBr->getSuccessor(0); - - // OldSucc had multiple successors. If ToBB has multiple predecessors, then - // the edge between them would be critical, which we already took care of. - // If ToBB has single operand PHI node then take care of it here. - FoldSingleEntryPHINodes(ToBB); - - // Update PHI nodes in OldSucc to know that FromBB no longer branches to it. - OldSucc->removePredecessor(FromBB); - - // Change FromBr to branch to the new destination. - FromBr->setSuccessor(0, ToBB); - - MadeChange = true; -} - -bool CondProp::RevectorBlockTo(BasicBlock *FromBB, Value *Cond, BranchInst *BI){ - BranchInst *FromBr = cast(FromBB->getTerminator()); - if (!FromBr->isUnconditional()) - return false; - - // Get the old block we are threading through. - BasicBlock *OldSucc = FromBr->getSuccessor(0); - - // If the condition is a constant, simply revector the unconditional branch at - // the end of FromBB to one of the successors of its current successor. - if (ConstantInt *CB = dyn_cast(Cond)) { - BasicBlock *ToBB = BI->getSuccessor(CB->isZero()); - - // OldSucc had multiple successors. If ToBB has multiple predecessors, then - // the edge between them would be critical, which we already took care of. - // If ToBB has single operand PHI node then take care of it here. - FoldSingleEntryPHINodes(ToBB); - - // Update PHI nodes in OldSucc to know that FromBB no longer branches to it. - OldSucc->removePredecessor(FromBB); - - // Change FromBr to branch to the new destination. - FromBr->setSuccessor(0, ToBB); - } else { - BasicBlock *Succ0 = BI->getSuccessor(0); - // Do not perform transform if the new destination has PHI nodes. The - // transform will add new preds to the PHI's. - if (isa(Succ0->begin())) - return false; - - BasicBlock *Succ1 = BI->getSuccessor(1); - if (isa(Succ1->begin())) - return false; - - // Insert the new conditional branch. - BranchInst::Create(Succ0, Succ1, Cond, FromBr); - - FoldSingleEntryPHINodes(Succ0); - FoldSingleEntryPHINodes(Succ1); - - // Update PHI nodes in OldSucc to know that FromBB no longer branches to it. - OldSucc->removePredecessor(FromBB); - - // Delete the old branch. - FromBr->eraseFromParent(); - } - - MadeChange = true; - return true; -} Modified: llvm/trunk/lib/Transforms/Scalar/Scalar.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalar.cpp?rev=86810&r1=86809&r2=86810&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/Scalar.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Tue Nov 10 23:56:35 2009 @@ -26,10 +26,6 @@ unwrap(PM)->add(createCFGSimplificationPass()); } -void LLVMAddCondPropagationPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createCondPropagationPass()); -} - void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM) { unwrap(PM)->add(createDeadStoreEliminationPass()); } From sabre at nondot.org Wed Nov 11 00:42:11 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 00:42:11 -0600 Subject: [llvm-commits] CVS: llvm-www/OpenProjects.html Message-ID: <200911110642.nAB6gBr4023978@zion.cs.uiuc.edu> Changes in directory llvm-www: OpenProjects.html updated: 1.55 -> 1.56 --- Log message: logo done. --- Diffs of the changes: (+1 -2) OpenProjects.html | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm-www/OpenProjects.html diff -u llvm-www/OpenProjects.html:1.55 llvm-www/OpenProjects.html:1.56 --- llvm-www/OpenProjects.html:1.55 Tue Nov 10 23:24:12 2009 +++ llvm-www/OpenProjects.html Wed Nov 11 00:41:50 2009 @@ -475,7 +475,6 @@ opt crashes, use bugpoint to reduce the test case and post it to a website or mailing list. Repeat ad infinitum.
  • -
  • Design a simple, recognizable logo.
  • Add sandbox features to the Interpreter: catch invalid memory accesses, potentially unsafe operations (access via arbitrary memory pointer) etc.
  • @@ -501,7 +500,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> LLVM Compiler Infrastructure
    - Last modified: $Date: 2009/11/11 05:24:12 $ + Last modified: $Date: 2009/11/11 06:41:50 $ From evan.cheng at apple.com Wed Nov 11 01:05:38 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 10 Nov 2009 23:05:38 -0800 Subject: [llvm-commits] [llvm] r86791 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp In-Reply-To: <200911110247.nAB2lJjM014802@zion.cs.uiuc.edu> References: <200911110247.nAB2lJjM014802@zion.cs.uiuc.edu> Message-ID: <90A068C9-E8C3-4C2D-B186-838F68F053C0@apple.com> Is this done during OptimizeThumb2JumpTables? Then I don't think that would work. It will mess up constant island placements. Perhaps this has to be done before the constant islands part? Or even in the bb placement optimization pass (which should be safe to turn on for ARM now)? Evan On Nov 10, 2009, at 6:47 PM, Jim Grosbach wrote: > Author: grosbach > Date: Tue Nov 10 20:47:19 2009 > New Revision: 86791 > > URL: http://llvm.org/viewvc/llvm-project?rev=86791&view=rev > Log: > > The TBB and TBH instructions for Thumb2 are really handy for jump > tables, but > can only branch forward. To best take advantage of them, we'd like > to adjust > the basic blocks around a bit when reasonable. This patch puts > basics in place > to do that, with a super-simple algorithm for backwards jump table > targets that > creates a new branch after the jump table which branches backwards. > Real > heuristics for reordering blocks or other modifications rather than > inserting > branches will follow. > > > Modified: > llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp > > Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=86791&r1=86790&r2=86791&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Tue Nov 10 > 20:47:19 2009 > @@ -31,6 +31,7 @@ > #include "llvm/ADT/SmallVector.h" > #include "llvm/ADT/STLExtras.h" > #include "llvm/ADT/Statistic.h" > +#include "llvm/Support/CommandLine.h" > #include > using namespace llvm; > > @@ -42,6 +43,12 @@ > STATISTIC(NumT2CPShrunk, "Number of Thumb2 constantpool instructions > shrunk"); > STATISTIC(NumT2BrShrunk, "Number of Thumb2 immediate branches > shrunk"); > STATISTIC(NumCBZ, "Number of CBZ / CBNZ formed"); > +STATISTIC(NumJTMoved, "Number of jump table destination blocks > moved"); > + > + > +static cl::opt > +AdjustJumpTableBlocks("arm-adjust-jump-tables", cl::Hidden, cl::init > (false), > + cl::desc("Adjust basic block layout to better use TB > [BH]")); > > namespace { > /// ARMConstantIslands - Due to limited PC-relative displacements, > ARM > @@ -202,6 +209,8 @@ > bool OptimizeThumb2Instructions(MachineFunction &MF); > bool OptimizeThumb2Branches(MachineFunction &MF); > bool OptimizeThumb2JumpTables(MachineFunction &MF); > + MachineBasicBlock *AdjustJTTargetBlockForward(MachineBasicBlock > *BB, > + MachineBasicBlock > *JTBB); > > unsigned GetOffsetOf(MachineInstr *MI) const; > void dumpBBs(); > @@ -1560,7 +1569,7 @@ > > // FIXME: After the tables are shrunk, can we get rid some of the > // constantpool tables? > - const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); > + MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); > const std::vector &JT = MJTI->getJumpTables > (); > for (unsigned i = 0, e = T2JumpTables.size(); i != e; ++i) { > MachineInstr *MI = T2JumpTables[i]; > @@ -1571,10 +1580,33 @@ > unsigned JTI = JTOP.getIndex(); > assert(JTI < JT.size()); > > - bool ByteOk = true; > - bool HalfWordOk = true; > + // We prefer if target blocks for the jump table come after the > jump > + // instruction so we can use TB[BH]. Loop through the target > blocks > + // and try to adjust them such that that's true. > unsigned JTOffset = GetOffsetOf(MI) + 4; > const std::vector &JTBBs = JT[JTI].MBBs; > + if (AdjustJumpTableBlocks) { > + for (unsigned j = 0, ee = JTBBs.size(); j != ee; ++j) { > + MachineBasicBlock *MBB = JTBBs[j]; > + unsigned DstOffset = BBOffsets[MBB->getNumber()]; > + > + if (DstOffset < JTOffset) { > + // The destination precedes the switch. Try to move the > block forward > + // so we have a positive offset. > + MachineBasicBlock *NewBB = > + AdjustJTTargetBlockForward(MBB, MI->getParent()); > + if (NewBB) { > + MJTI->ReplaceMBBInJumpTables(JTBBs[j], NewBB); > + JTOffset = GetOffsetOf(MI) + 4; > + DstOffset = BBOffsets[MBB->getNumber()]; > + } > + } > + } > + } > + > + bool ByteOk = true; > + bool HalfWordOk = true; > + JTOffset = GetOffsetOf(MI) + 4; > for (unsigned j = 0, ee = JTBBs.size(); j != ee; ++j) { > MachineBasicBlock *MBB = JTBBs[j]; > unsigned DstOffset = BBOffsets[MBB->getNumber()]; > @@ -1660,3 +1692,64 @@ > > return MadeChange; > } > + > +MachineBasicBlock *ARMConstantIslands:: > +AdjustJTTargetBlockForward(MachineBasicBlock *BB, MachineBasicBlock > *JTBB) > +{ > + MachineFunction &MF = *BB->getParent(); > + > + // FIXME: For now, instead of moving the block, we'll create a > new block > + // immediate following the jump that's an unconditional branch to > the > + // actual target. This is obviously not what we want for a real > solution, > + // but it's useful for proof of concept, and it may be a useful > fallback > + // later for cases where we otherwise can't move a block. > + > + // Create a new MBB for the code after the jump BB. > + MachineBasicBlock *NewBB = > + MF.CreateMachineBasicBlock(JTBB->getBasicBlock()); > + MachineFunction::iterator MBBI = JTBB; ++MBBI; > + MF.insert(MBBI, NewBB); > + > + // Add an unconditional branch from NewBB to BB. > + // There doesn't seem to be meaningful DebugInfo available; this > doesn't > + // correspond directly to anything in the source. > + assert (isThumb2 && "Adjusting for TB[BH] but not in Thumb2?"); > + BuildMI(NewBB, DebugLoc::getUnknownLoc(), TII->get > (ARM::t2B)).addMBB(BB); > + > + // Update the CFG. > + NewBB->addSuccessor(BB); > + JTBB->removeSuccessor(BB); > + JTBB->addSuccessor(NewBB); > + > + // Update internal data structures to account for the newly > inserted MBB. > + // This is almost the same as UpdateForInsertedWaterBlock, except > that > + // the Water goes after OrigBB, not NewBB. > + MF.RenumberBlocks(NewBB); > + > + // Insert a size into BBSizes to align it properly with the (newly > + // renumbered) block numbers. > + BBSizes.insert(BBSizes.begin()+NewBB->getNumber(), 0); > + > + // Likewise for BBOffsets. > + BBOffsets.insert(BBOffsets.begin()+NewBB->getNumber(), 0); > + > + // Figure out how large the first NewMBB is. > + unsigned NewBBSize = 0; > + for (MachineBasicBlock::iterator I = NewBB->begin(), E = NewBB- > >end(); > + I != E; ++I) > + NewBBSize += TII->GetInstSizeInBytes(I); > + > + unsigned NewBBI = NewBB->getNumber(); > + unsigned JTBBI = JTBB->getNumber(); > + // Set the size of NewBB in BBSizes. > + BBSizes[NewBBI] = NewBBSize; > + > + // ...and adjust BBOffsets for NewBB accordingly. > + BBOffsets[NewBBI] = BBOffsets[JTBBI] + BBSizes[JTBBI]; > + > + // All BBOffsets following these blocks must be modified. > + AdjustBBOffsetsAfter(NewBB, 4); > + > + ++NumJTMoved; > + return NewBB; > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Wed Nov 11 01:11:03 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 11 Nov 2009 07:11:03 -0000 Subject: [llvm-commits] [llvm] r86814 - in /llvm/trunk/test/CodeGen/X86: loop-strength-reduce2.ll loop-strength-reduce3.ll loop-strength-reduce5.ll loop-strength-reduce6.ll Message-ID: <200911110711.nAB7B3kx024811@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 11 01:11:02 2009 New Revision: 86814 URL: http://llvm.org/viewvc/llvm-project?rev=86814&view=rev Log: Add nounwind. Modified: llvm/trunk/test/CodeGen/X86/loop-strength-reduce2.ll llvm/trunk/test/CodeGen/X86/loop-strength-reduce3.ll llvm/trunk/test/CodeGen/X86/loop-strength-reduce5.ll llvm/trunk/test/CodeGen/X86/loop-strength-reduce6.ll Modified: llvm/trunk/test/CodeGen/X86/loop-strength-reduce2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce2.ll?rev=86814&r1=86813&r2=86814&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce2.ll (original) +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce2.ll Wed Nov 11 01:11:02 2009 @@ -4,7 +4,7 @@ @flags2 = internal global [8193 x i8] zeroinitializer, align 32 ; <[8193 x i8]*> [#uses=1] -define void @test(i32 %k, i32 %i) { +define void @test(i32 %k, i32 %i) nounwind { entry: %k_addr.012 = shl i32 %i, 1 ; [#uses=1] %tmp14 = icmp sgt i32 %k_addr.012, 8192 ; [#uses=1] Modified: llvm/trunk/test/CodeGen/X86/loop-strength-reduce3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce3.ll?rev=86814&r1=86813&r2=86814&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce3.ll (original) +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce3.ll Wed Nov 11 01:11:02 2009 @@ -1,7 +1,7 @@ ; RUN: llc < %s -march=x86 | grep cmp | grep 240 ; RUN: llc < %s -march=x86 | grep inc | count 1 -define i32 @foo(i32 %A, i32 %B, i32 %C, i32 %D) { +define i32 @foo(i32 %A, i32 %B, i32 %C, i32 %D) nounwind { entry: %tmp2955 = icmp sgt i32 %C, 0 ; [#uses=1] br i1 %tmp2955, label %bb26.outer.us, label %bb40.split Modified: llvm/trunk/test/CodeGen/X86/loop-strength-reduce5.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce5.ll?rev=86814&r1=86813&r2=86814&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce5.ll (original) +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce5.ll Wed Nov 11 01:11:02 2009 @@ -3,7 +3,7 @@ @X = weak global i16 0 ; [#uses=1] @Y = weak global i16 0 ; [#uses=1] -define void @foo(i32 %N) { +define void @foo(i32 %N) nounwind { entry: %tmp1019 = icmp sgt i32 %N, 0 ; [#uses=1] br i1 %tmp1019, label %bb, label %return Modified: llvm/trunk/test/CodeGen/X86/loop-strength-reduce6.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce6.ll?rev=86814&r1=86813&r2=86814&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce6.ll (original) +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce6.ll Wed Nov 11 01:11:02 2009 @@ -1,6 +1,6 @@ ; RUN: llc < %s -march=x86-64 | not grep inc -define fastcc i32 @decodeMP3(i32 %isize, i32* %done) { +define fastcc i32 @decodeMP3(i32 %isize, i32* %done) nounwind { entry: br i1 false, label %cond_next191, label %cond_true189 From baldrick at free.fr Wed Nov 11 07:43:11 2009 From: baldrick at free.fr (Duncan Sands) Date: Wed, 11 Nov 2009 13:43:11 -0000 Subject: [llvm-commits] [dragonegg] r86838 - in /dragonegg/trunk: llvm-convert.cpp llvm-internal.h Message-ID: <200911111343.nABDhBfh021593@zion.cs.uiuc.edu> Author: baldrick Date: Wed Nov 11 07:43:10 2009 New Revision: 86838 URL: http://llvm.org/viewvc/llvm-project?rev=86838&view=rev Log: It seems that the intent is that llvm.invariant.start should not require a corresponding call to llvm.invariant.end. The fact that this doesn't work is an LLVM bug... So stop trying to output calls to llvm.invariant.end all over the place. Modified: dragonegg/trunk/llvm-convert.cpp dragonegg/trunk/llvm-internal.h Modified: dragonegg/trunk/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=86838&r1=86837&r2=86838&view=diff ============================================================================== --- dragonegg/trunk/llvm-convert.cpp (original) +++ dragonegg/trunk/llvm-convert.cpp Wed Nov 11 07:43:10 2009 @@ -763,26 +763,6 @@ typedef SmallVector, 8> TreeVector; typedef SmallVector, 8> ValueVector; -/// EndInvariantRegions - Output a call to llvm.invariant.end for each call -/// to llvm.invariant.start recorded in InvariantRegions. -void TreeToLLVM::EndInvariantRegions() { - if (InvariantRegions.empty()) - return; - - Value *Ops[3]; - Value *IEnd = Intrinsic::getDeclaration(TheModule,Intrinsic::invariant_end); - for (unsigned i = 0, e = InvariantRegions.size(); i < e; ++i) { - CallInst *CI = InvariantRegions[i]; - Ops[0] = CI; - Ops[1] = CI->getOperand(1); - Ops[2] = CI->getOperand(2); - Builder.CreateCall(IEnd, Ops, Ops + 3); - } - - // Do not clear out InvariantRegions in case the function has multiple exits: - // we need to output calls to llvm.invariant.end before each one. -} - /// PopulatePhiNodes - Populate generated phi nodes with their operands. void TreeToLLVM::PopulatePhiNodes() { PredVector Predecessors; @@ -949,9 +929,6 @@ TheDebugInfo->EmitStopPoint(Fn, Builder.GetInsertBlock(), Builder); TheDebugInfo->EmitFunctionEnd(Builder.GetInsertBlock(), true); } - - EndInvariantRegions(); - if (RetVals.empty()) Builder.CreateRetVoid(); else if (RetVals.size() == 1 && RetVals[0]->getType() == Fn->getReturnType()){ @@ -2128,7 +2105,6 @@ if (UnwindBB) { CreateExceptionValues(); EmitBlock(UnwindBB); - EndInvariantRegions(); abort();//FIXME //FIXME // Fetch and store exception handler. //FIXME Value *Arg = Builder.CreateLoad(ExceptionValue, "eh_ptr"); @@ -2567,7 +2543,6 @@ // after the function to prevent LLVM from thinking that control flow will // fall into the subsequent block. if (gimple_call_flags(stmt) & ECF_NORETURN) { - EndInvariantRegions(); Builder.CreateUnreachable(); EmitBlock(BasicBlock::Create(Context)); } @@ -4638,7 +4613,6 @@ case BUILT_IN_TRAP: Builder.CreateCall(Intrinsic::getDeclaration(TheModule, Intrinsic::trap)); // Emit an explicit unreachable instruction. - EndInvariantRegions(); Builder.CreateUnreachable(); EmitBlock(BasicBlock::Create(Context)); return true; @@ -5485,7 +5459,6 @@ Args.push_back(Handler); Builder.CreateCall(Intrinsic::getDeclaration(TheModule, IID), Args.begin(), Args.end()); - EndInvariantRegions(); Result = Builder.CreateUnreachable(); EmitBlock(BasicBlock::Create(Context)); @@ -5699,26 +5672,6 @@ // is called. static const Type *VPTy = Type::getInt8PtrTy(Context); - // In order to simplify the use of llvm.invariant.start/end, generate the - // trampoline initialization code in the entry block. - BasicBlock *EntryBlock = Fn->begin(); - - // Note the current builder position. - BasicBlock *SavedInsertBB = Builder.GetInsertBlock(); - BasicBlock::iterator SavedInsertPoint = Builder.GetInsertPoint(); - - // Pop the entry block terminator. There may not be a terminator if the entry - // block was not yet finished. - Instruction *Terminator = EntryBlock->getTerminator(); - assert(((SavedInsertBB != EntryBlock && Terminator) || - (SavedInsertPoint == EntryBlock->end() && !Terminator)) && - "Insertion point doesn't make sense!"); - if (Terminator) - Terminator->removeFromParent(); - - // Point the builder at the end of the entry block. - Builder.SetInsertPoint(EntryBlock); - // Create a stack temporary to hold the trampoline machine code. const Type *TrampType = ArrayType::get(Type::getInt8Ty(Context), TRAMPOLINE_SIZE); @@ -5755,16 +5708,7 @@ Intr = Intrinsic::getDeclaration(TheModule, Intrinsic::invariant_start); Ops[0] = ConstantInt::get(Type::getInt64Ty(Context), TRAMPOLINE_SIZE); Ops[1] = Builder.CreateBitCast(Tramp, VPTy); - CallInst *InvStart = Builder.CreateCall(Intr, Ops, Ops + 2); - InvariantRegions.push_back(InvStart); - - // Restore the entry block terminator. - if (Terminator) - EntryBlock->getInstList().push_back(Terminator); - - // Restore the builder insertion point. - if (SavedInsertBB != EntryBlock) - Builder.SetInsertPoint(SavedInsertBB, SavedInsertPoint); + Builder.CreateCall(Intr, Ops, Ops + 2); return true; } Modified: dragonegg/trunk/llvm-internal.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-internal.h?rev=86838&r1=86837&r2=86838&view=diff ============================================================================== --- dragonegg/trunk/llvm-internal.h (original) +++ dragonegg/trunk/llvm-internal.h Wed Nov 11 07:43:10 2009 @@ -357,10 +357,6 @@ /// LocalDecls - Map from local declarations to their associated LLVM values. DenseMap > LocalDecls; - /// InvariantRegions - Calls to llvm.invariant.start for which a corresponding - /// call to llvm.invariant.end needs to be generated at function exit points. - SmallVector InvariantRegions; - /// PendingPhis - Phi nodes which have not yet been populated with operands. SmallVector PendingPhis; @@ -473,15 +469,11 @@ /// StartFunctionBody - Start the emission of 'fndecl', outputing all /// declarations for parameters and setting things up. void StartFunctionBody(); - + /// FinishFunctionBody - Once the body of the function has been emitted, this /// cleans up and returns the result function. Function *FinishFunctionBody(); - /// EndInvariantRegions - Output a call to llvm.invariant.end for each call - /// of llvm.invariant.start recorded in InvariantRegions. - void EndInvariantRegions(); - /// PopulatePhiNodes - Populate generated phi nodes with their operands. void PopulatePhiNodes(); From baldrick at free.fr Wed Nov 11 09:34:13 2009 From: baldrick at free.fr (Duncan Sands) Date: Wed, 11 Nov 2009 15:34:13 -0000 Subject: [llvm-commits] [llvm] r86840 - in /llvm/trunk: include/llvm/IntrinsicInst.h lib/Transforms/Utils/Local.cpp test/Transforms/InstCombine/invariant.ll Message-ID: <200911111534.nABFYEd0025670@zion.cs.uiuc.edu> Author: baldrick Date: Wed Nov 11 09:34:13 2009 New Revision: 86840 URL: http://llvm.org/viewvc/llvm-project?rev=86840&view=rev Log: Don't trivially delete unused calls to llvm.invariant.start. This allows llvm.invariant.start to be used without necessarily being paired with a call to llvm.invariant.end. If you run the entire optimization pipeline then such calls are in fact deleted (adce does it), but that's actually a good thing since we probably do want them to be zapped late in the game. There should really be an integration test that checks that the llvm.invariant.start call lasts long enough that all passes that do interesting things with it get to do their stuff before it is deleted. But since no passes do anything interesting with it yet this will have to wait for later. Added: llvm/trunk/test/Transforms/InstCombine/invariant.ll Modified: llvm/trunk/include/llvm/IntrinsicInst.h llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/include/llvm/IntrinsicInst.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicInst.h?rev=86840&r1=86839&r2=86840&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicInst.h (original) +++ llvm/trunk/include/llvm/IntrinsicInst.h Wed Nov 11 09:34:13 2009 @@ -320,6 +320,28 @@ } }; + /// MemoryUseIntrinsic - This is the common base class for the memory use + /// marker intrinsics. + /// + struct MemoryUseIntrinsic : public IntrinsicInst { + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const MemoryUseIntrinsic *) { return true; } + static inline bool classof(const IntrinsicInst *I) { + switch (I->getIntrinsicID()) { + case Intrinsic::lifetime_start: + case Intrinsic::lifetime_end: + case Intrinsic::invariant_start: + case Intrinsic::invariant_end: + return true; + default: return false; + } + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } + }; + } #endif Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=86840&r1=86839&r2=86840&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Wed Nov 11 09:34:13 2009 @@ -252,6 +252,9 @@ // We don't want debug info removed by anything this general. if (isa(I)) return false; + // Likewise for memory use markers. + if (isa(I)) return false; + if (!I->mayHaveSideEffects()) return true; // Special case intrinsics that "may have side effects" but can be deleted Added: llvm/trunk/test/Transforms/InstCombine/invariant.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/invariant.ll?rev=86840&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/invariant.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/invariant.ll Wed Nov 11 09:34:13 2009 @@ -0,0 +1,16 @@ +; Test to make sure unused llvm.invariant.start calls are not trivially eliminated +; RUN: opt < %s -instcombine -S | FileCheck %s + +declare void @g(i8*) + +declare { }* @llvm.invariant.start(i64, i8* nocapture) nounwind readonly + +define i8 @f() { + %a = alloca i8 ; [#uses=4] + store i8 0, i8* %a + %i = call { }* @llvm.invariant.start(i64 1, i8* %a) ; <{ }*> [#uses=0] + ; CHECK: call { }* @llvm.invariant.start + call void @g(i8* %a) + %r = load i8* %a ; [#uses=1] + ret i8 %r +} From grosbach at apple.com Wed Nov 11 10:40:28 2009 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 11 Nov 2009 08:40:28 -0800 Subject: [llvm-commits] [llvm] r86404 - in /llvm/trunk/lib/Target/ARM: ARMAddressingModes.h ARMISelDAGToDAG.cpp ARMInstrInfo.td AsmPrinter/ARMAsmPrinter.cpp NEONPreAllocPass.cpp In-Reply-To: <90BAE2B3-491D-4D6F-BA26-4A9CD2E54B84@apple.com> References: <200911072125.nA7LPdh9002578@zion.cs.uiuc.edu> <90BAE2B3-491D-4D6F-BA26-4A9CD2E54B84@apple.com> Message-ID: <07E25920-8744-4E1E-B020-292B6B32984A@apple.com> On Nov 10, 2009, at 1:27 AM, Evan Cheng wrote: > > On Nov 7, 2009, at 1:25 PM, Jim Grosbach wrote: > >> >> >> bool ARMDAGToDAGISel::SelectAddrMode6(SDValue Op, SDValue N, >> SDValue &Addr, SDValue &Update, >> - SDValue &Opc) { >> + SDValue &Opc, SDValue >> &Align) { >> Addr = N; >> // Default to no writeback. >> Update = CurDAG->getRegister(0, MVT::i32); >> Opc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(false), MVT::i32); >> + // Default to no alignment. >> + Align = CurDAG->getTargetConstant(0, MVT::i32); >> return true; >> } > > Shouldn't we be able to transfer the alignment on the LoadSDNode / > StoreSDNode to Align (capped at 64 / 128 for 64-bit / 128-bit memory > operations)? Potentially. I'm concerned about stack objects in frames we don't dynamically align, however. That could result in aligned load/stores of objects w/o guaranteed alignment, and I wanted to avoid that. I've been wondering about the best approach for that. We could do the alignment anyway and consider the additional dynamic alignment situations (VLAs and such) to be optimization opportunities. Or we could let the user specify alignment as an optional operand to the NEON builtins. That doesn't help with any auto-vectorizing stuff we may do, however. I tend to prefer the first option. What do you think? > > Evan > >> >> @@ -1008,8 +1010,8 @@ >> SDNode *N = Op.getNode(); >> DebugLoc dl = N->getDebugLoc(); >> >> - SDValue MemAddr, MemUpdate, MemOpc; >> - if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, >> MemOpc)) >> + SDValue MemAddr, MemUpdate, MemOpc, Align; >> + if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, >> MemOpc, Align)) >> return NULL; >> >> SDValue Chain = N->getOperand(0); >> @@ -1034,10 +1036,10 @@ >> >> if (is64BitVector) { >> unsigned Opc = DOpcodes[OpcodeIndex]; >> - const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Chain }; >> + const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Align, >> Chain }; >> std::vector ResTys(NumVecs, VT); >> ResTys.push_back(MVT::Other); >> - return CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 4); >> + return CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5); >> } >> >> EVT RegVT = GetNEONSubregVT(VT); >> @@ -1045,10 +1047,10 @@ >> // Quad registers are directly supported for VLD2, >> // loading 2 pairs of D regs. >> unsigned Opc = QOpcodes0[OpcodeIndex]; >> - const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Chain }; >> + const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Align, >> Chain }; >> std::vector ResTys(4, VT); >> ResTys.push_back(MVT::Other); >> - SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 4); >> + SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5); >> Chain = SDValue(VLd, 4); >> >> // Combine the even and odd subregs to produce the result. >> @@ -1069,14 +1071,15 @@ >> >> // Load the even subregs. >> unsigned Opc = QOpcodes0[OpcodeIndex]; >> - const SDValue OpsA[] = { MemAddr, MemUpdate, MemOpc, Chain }; >> - SDNode *VLdA = CurDAG->getMachineNode(Opc, dl, ResTys, OpsA, 4); >> + const SDValue OpsA[] = { MemAddr, MemUpdate, MemOpc, Align, >> Chain }; >> + SDNode *VLdA = CurDAG->getMachineNode(Opc, dl, ResTys, OpsA, 5); >> Chain = SDValue(VLdA, NumVecs+1); >> >> // Load the odd subregs. >> Opc = QOpcodes1[OpcodeIndex]; >> - const SDValue OpsB[] = { SDValue(VLdA, NumVecs), MemUpdate, >> MemOpc, Chain }; >> - SDNode *VLdB = CurDAG->getMachineNode(Opc, dl, ResTys, OpsB, 4); >> + const SDValue OpsB[] = { SDValue(VLdA, NumVecs), MemUpdate, >> MemOpc, >> + Align, Chain }; >> + SDNode *VLdB = CurDAG->getMachineNode(Opc, dl, ResTys, OpsB, 5); >> Chain = SDValue(VLdB, NumVecs+1); >> >> // Combine the even and odd subregs to produce the result. >> @@ -1096,8 +1099,8 @@ >> SDNode *N = Op.getNode(); >> DebugLoc dl = N->getDebugLoc(); >> >> - SDValue MemAddr, MemUpdate, MemOpc; >> - if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, >> MemOpc)) >> + SDValue MemAddr, MemUpdate, MemOpc, Align; >> + if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, >> MemOpc, Align)) >> return NULL; >> >> SDValue Chain = N->getOperand(0); >> @@ -1124,13 +1127,14 @@ >> Ops.push_back(MemAddr); >> Ops.push_back(MemUpdate); >> Ops.push_back(MemOpc); >> + Ops.push_back(Align); >> >> if (is64BitVector) { >> unsigned Opc = DOpcodes[OpcodeIndex]; >> for (unsigned Vec = 0; Vec < NumVecs; ++Vec) >> Ops.push_back(N->getOperand(Vec+3)); >> Ops.push_back(Chain); >> - return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), >> NumVecs+4); >> + return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), >> NumVecs+5); >> } >> >> EVT RegVT = GetNEONSubregVT(VT); >> @@ -1145,7 +1149,7 @@ >> N->getOperand(Vec >> +3))); >> } >> Ops.push_back(Chain); >> - return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), >> 8); >> + return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), >> 9); >> } >> >> // Otherwise, quad registers are stored with two separate >> instructions, >> @@ -1161,18 +1165,18 @@ >> Ops.push_back(Chain); >> unsigned Opc = QOpcodes0[OpcodeIndex]; >> SDNode *VStA = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType >> (), >> - MVT::Other, Ops.data(), >> NumVecs+4); >> + MVT::Other, Ops.data(), >> NumVecs+5); >> Chain = SDValue(VStA, 1); >> >> // Store the odd subregs. >> Ops[0] = SDValue(VStA, 0); // MemAddr >> for (unsigned Vec = 0; Vec < NumVecs; ++Vec) >> - Ops[Vec+3] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, >> dl, RegVT, >> + Ops[Vec+4] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, >> dl, RegVT, >> N->getOperand(Vec+3)); >> - Ops[NumVecs+3] = Chain; >> + Ops[NumVecs+4] = Chain; >> Opc = QOpcodes1[OpcodeIndex]; >> SDNode *VStB = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType >> (), >> - MVT::Other, Ops.data(), >> NumVecs+4); >> + MVT::Other, Ops.data(), >> NumVecs+5); >> Chain = SDValue(VStB, 1); >> ReplaceUses(SDValue(N, 0), Chain); >> return NULL; >> @@ -1186,8 +1190,8 @@ >> SDNode *N = Op.getNode(); >> DebugLoc dl = N->getDebugLoc(); >> >> - SDValue MemAddr, MemUpdate, MemOpc; >> - if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, >> MemOpc)) >> + SDValue MemAddr, MemUpdate, MemOpc, Align; >> + if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, >> MemOpc, Align)) >> return NULL; >> >> SDValue Chain = N->getOperand(0); >> @@ -1224,6 +1228,7 @@ >> Ops.push_back(MemAddr); >> Ops.push_back(MemUpdate); >> Ops.push_back(MemOpc); >> + Ops.push_back(Align); >> >> unsigned Opc = 0; >> if (is64BitVector) { >> >> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=86404&r1=86403&r2=86404&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) >> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Sat Nov 7 15:25:39 >> 2009 >> @@ -340,9 +340,9 @@ >> // addrmode6 := reg with optional writeback >> // >> def addrmode6 : Operand, >> - ComplexPattern { >> + ComplexPattern { >> let PrintMethod = "printAddrMode6Operand"; >> - let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm); >> + let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm); >> } >> >> // addrmodepc := pc + reg >> >> Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=86404&r1=86403&r2=86404&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) >> +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Sat Nov >> 7 15:25:39 2009 >> @@ -638,9 +638,17 @@ >> const MachineOperand &MO1 = MI->getOperand(Op); >> const MachineOperand &MO2 = MI->getOperand(Op+1); >> const MachineOperand &MO3 = MI->getOperand(Op+2); >> + const MachineOperand &MO4 = MI->getOperand(Op+3); >> >> - // FIXME: No support yet for specifying alignment. >> - O << "[" << getRegisterName(MO1.getReg()) << "]"; >> + O << "[" << getRegisterName(MO1.getReg()); >> + if (MO4.getImm()) { >> + if (Subtarget->isTargetDarwin()) >> + O << ", :"; >> + else >> + O << " @"; >> + O << MO4.getImm(); >> + } >> + O << "]"; >> >> if (ARM_AM::getAM6WBFlag(MO3.getImm())) { >> if (MO2.getReg() == 0) >> >> Modified: llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp?rev=86404&r1=86403&r2=86404&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp (original) >> +++ llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp Sat Nov 7 >> 15:25:39 2009 >> @@ -177,20 +177,20 @@ >> case ARM::VST2LNd8: >> case ARM::VST2LNd16: >> case ARM::VST2LNd32: >> - FirstOpnd = 3; >> + FirstOpnd = 4; >> NumRegs = 2; >> return true; >> >> case ARM::VST2q8: >> case ARM::VST2q16: >> case ARM::VST2q32: >> - FirstOpnd = 3; >> + FirstOpnd = 4; >> NumRegs = 4; >> return true; >> >> case ARM::VST2LNq16a: >> case ARM::VST2LNq32a: >> - FirstOpnd = 3; >> + FirstOpnd = 4; >> NumRegs = 2; >> Offset = 0; >> Stride = 2; >> @@ -198,7 +198,7 @@ >> >> case ARM::VST2LNq16b: >> case ARM::VST2LNq32b: >> - FirstOpnd = 3; >> + FirstOpnd = 4; >> NumRegs = 2; >> Offset = 1; >> Stride = 2; >> @@ -211,14 +211,14 @@ >> case ARM::VST3LNd8: >> case ARM::VST3LNd16: >> case ARM::VST3LNd32: >> - FirstOpnd = 3; >> + FirstOpnd = 4; >> NumRegs = 3; >> return true; >> >> case ARM::VST3q8a: >> case ARM::VST3q16a: >> case ARM::VST3q32a: >> - FirstOpnd = 4; >> + FirstOpnd = 5; >> NumRegs = 3; >> Offset = 0; >> Stride = 2; >> @@ -227,7 +227,7 @@ >> case ARM::VST3q8b: >> case ARM::VST3q16b: >> case ARM::VST3q32b: >> - FirstOpnd = 4; >> + FirstOpnd = 5; >> NumRegs = 3; >> Offset = 1; >> Stride = 2; >> @@ -235,7 +235,7 @@ >> >> case ARM::VST3LNq16a: >> case ARM::VST3LNq32a: >> - FirstOpnd = 3; >> + FirstOpnd = 4; >> NumRegs = 3; >> Offset = 0; >> Stride = 2; >> @@ -243,7 +243,7 @@ >> >> case ARM::VST3LNq16b: >> case ARM::VST3LNq32b: >> - FirstOpnd = 3; >> + FirstOpnd = 4; >> NumRegs = 3; >> Offset = 1; >> Stride = 2; >> @@ -256,14 +256,14 @@ >> case ARM::VST4LNd8: >> case ARM::VST4LNd16: >> case ARM::VST4LNd32: >> - FirstOpnd = 3; >> + FirstOpnd = 4; >> NumRegs = 4; >> return true; >> >> case ARM::VST4q8a: >> case ARM::VST4q16a: >> case ARM::VST4q32a: >> - FirstOpnd = 4; >> + FirstOpnd = 5; >> NumRegs = 4; >> Offset = 0; >> Stride = 2; >> @@ -272,7 +272,7 @@ >> case ARM::VST4q8b: >> case ARM::VST4q16b: >> case ARM::VST4q32b: >> - FirstOpnd = 4; >> + FirstOpnd = 5; >> NumRegs = 4; >> Offset = 1; >> Stride = 2; >> @@ -280,7 +280,7 @@ >> >> case ARM::VST4LNq16a: >> case ARM::VST4LNq32a: >> - FirstOpnd = 3; >> + FirstOpnd = 4; >> NumRegs = 4; >> Offset = 0; >> Stride = 2; >> @@ -288,7 +288,7 @@ >> >> case ARM::VST4LNq16b: >> case ARM::VST4LNq32b: >> - FirstOpnd = 3; >> + FirstOpnd = 4; >> NumRegs = 4; >> Offset = 1; >> Stride = 2; >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From grosbach at apple.com Wed Nov 11 11:22:41 2009 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 11 Nov 2009 09:22:41 -0800 Subject: [llvm-commits] [llvm] r86791 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp In-Reply-To: <90A068C9-E8C3-4C2D-B186-838F68F053C0@apple.com> References: <200911110247.nAB2lJjM014802@zion.cs.uiuc.edu> <90A068C9-E8C3-4C2D-B186-838F68F053C0@apple.com> Message-ID: Yeah, it definitely should be moved. That's one of the things I'm going to do this morning. We could do it in the placement optimization pass, but I'm a bit hesitant at this point since a fair bit of the information we may use for determining how and whether to make transformations will be target specific. The ranges of the TB[BH] instructions being the most straightforward example. That may be handleable via target hooks or something, though. Once we have a better handle on the specifics of the heuristics, that should be more apparent. Why was the code placement opt unsafe for arm before? I don't recall the history there. -Jim On Nov 10, 2009, at 11:05 PM, Evan Cheng wrote: > Is this done during OptimizeThumb2JumpTables? Then I don't think > that would work. It will mess up constant island placements. Perhaps > this has to be done before the constant islands part? Or even in the > bb placement optimization pass (which should be safe to turn on for > ARM now)? > > Evan > > On Nov 10, 2009, at 6:47 PM, Jim Grosbach wrote: > >> Author: grosbach >> Date: Tue Nov 10 20:47:19 2009 >> New Revision: 86791 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=86791&view=rev >> Log: >> >> The TBB and TBH instructions for Thumb2 are really handy for jump >> tables, but >> can only branch forward. To best take advantage of them, we'd like >> to adjust >> the basic blocks around a bit when reasonable. This patch puts >> basics in place >> to do that, with a super-simple algorithm for backwards jump table >> targets that >> creates a new branch after the jump table which branches backwards. >> Real >> heuristics for reordering blocks or other modifications rather than >> inserting >> branches will follow. >> >> >> Modified: >> llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp >> >> Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=86791&r1=86790&r2=86791&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) >> +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Tue Nov 10 >> 20:47:19 2009 >> @@ -31,6 +31,7 @@ >> #include "llvm/ADT/SmallVector.h" >> #include "llvm/ADT/STLExtras.h" >> #include "llvm/ADT/Statistic.h" >> +#include "llvm/Support/CommandLine.h" >> #include >> using namespace llvm; >> >> @@ -42,6 +43,12 @@ >> STATISTIC(NumT2CPShrunk, "Number of Thumb2 constantpool >> instructions shrunk"); >> STATISTIC(NumT2BrShrunk, "Number of Thumb2 immediate branches >> shrunk"); >> STATISTIC(NumCBZ, "Number of CBZ / CBNZ formed"); >> +STATISTIC(NumJTMoved, "Number of jump table destination blocks >> moved"); >> + >> + >> +static cl::opt >> +AdjustJumpTableBlocks("arm-adjust-jump-tables", cl::Hidden, >> cl::init(false), >> + cl::desc("Adjust basic block layout to better use TB >> [BH]")); >> >> namespace { >> /// ARMConstantIslands - Due to limited PC-relative displacements, >> ARM >> @@ -202,6 +209,8 @@ >> bool OptimizeThumb2Instructions(MachineFunction &MF); >> bool OptimizeThumb2Branches(MachineFunction &MF); >> bool OptimizeThumb2JumpTables(MachineFunction &MF); >> + MachineBasicBlock *AdjustJTTargetBlockForward >> (MachineBasicBlock *BB, >> + >> MachineBasicBlock *JTBB); >> >> unsigned GetOffsetOf(MachineInstr *MI) const; >> void dumpBBs(); >> @@ -1560,7 +1569,7 @@ >> >> // FIXME: After the tables are shrunk, can we get rid some of the >> // constantpool tables? >> - const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); >> + MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); >> const std::vector &JT = MJTI->getJumpTables >> (); >> for (unsigned i = 0, e = T2JumpTables.size(); i != e; ++i) { >> MachineInstr *MI = T2JumpTables[i]; >> @@ -1571,10 +1580,33 @@ >> unsigned JTI = JTOP.getIndex(); >> assert(JTI < JT.size()); >> >> - bool ByteOk = true; >> - bool HalfWordOk = true; >> + // We prefer if target blocks for the jump table come after >> the jump >> + // instruction so we can use TB[BH]. Loop through the target >> blocks >> + // and try to adjust them such that that's true. >> unsigned JTOffset = GetOffsetOf(MI) + 4; >> const std::vector &JTBBs = JT[JTI].MBBs; >> + if (AdjustJumpTableBlocks) { >> + for (unsigned j = 0, ee = JTBBs.size(); j != ee; ++j) { >> + MachineBasicBlock *MBB = JTBBs[j]; >> + unsigned DstOffset = BBOffsets[MBB->getNumber()]; >> + >> + if (DstOffset < JTOffset) { >> + // The destination precedes the switch. Try to move the >> block forward >> + // so we have a positive offset. >> + MachineBasicBlock *NewBB = >> + AdjustJTTargetBlockForward(MBB, MI->getParent()); >> + if (NewBB) { >> + MJTI->ReplaceMBBInJumpTables(JTBBs[j], NewBB); >> + JTOffset = GetOffsetOf(MI) + 4; >> + DstOffset = BBOffsets[MBB->getNumber()]; >> + } >> + } >> + } >> + } >> + >> + bool ByteOk = true; >> + bool HalfWordOk = true; >> + JTOffset = GetOffsetOf(MI) + 4; >> for (unsigned j = 0, ee = JTBBs.size(); j != ee; ++j) { >> MachineBasicBlock *MBB = JTBBs[j]; >> unsigned DstOffset = BBOffsets[MBB->getNumber()]; >> @@ -1660,3 +1692,64 @@ >> >> return MadeChange; >> } >> + >> +MachineBasicBlock *ARMConstantIslands:: >> +AdjustJTTargetBlockForward(MachineBasicBlock *BB, >> MachineBasicBlock *JTBB) >> +{ >> + MachineFunction &MF = *BB->getParent(); >> + >> + // FIXME: For now, instead of moving the block, we'll create a >> new block >> + // immediate following the jump that's an unconditional branch >> to the >> + // actual target. This is obviously not what we want for a real >> solution, >> + // but it's useful for proof of concept, and it may be a useful >> fallback >> + // later for cases where we otherwise can't move a block. >> + >> + // Create a new MBB for the code after the jump BB. >> + MachineBasicBlock *NewBB = >> + MF.CreateMachineBasicBlock(JTBB->getBasicBlock()); >> + MachineFunction::iterator MBBI = JTBB; ++MBBI; >> + MF.insert(MBBI, NewBB); >> + >> + // Add an unconditional branch from NewBB to BB. >> + // There doesn't seem to be meaningful DebugInfo available; this >> doesn't >> + // correspond directly to anything in the source. >> + assert (isThumb2 && "Adjusting for TB[BH] but not in Thumb2?"); >> + BuildMI(NewBB, DebugLoc::getUnknownLoc(), TII->get >> (ARM::t2B)).addMBB(BB); >> + >> + // Update the CFG. >> + NewBB->addSuccessor(BB); >> + JTBB->removeSuccessor(BB); >> + JTBB->addSuccessor(NewBB); >> + >> + // Update internal data structures to account for the newly >> inserted MBB. >> + // This is almost the same as UpdateForInsertedWaterBlock, >> except that >> + // the Water goes after OrigBB, not NewBB. >> + MF.RenumberBlocks(NewBB); >> + >> + // Insert a size into BBSizes to align it properly with the (newly >> + // renumbered) block numbers. >> + BBSizes.insert(BBSizes.begin()+NewBB->getNumber(), 0); >> + >> + // Likewise for BBOffsets. >> + BBOffsets.insert(BBOffsets.begin()+NewBB->getNumber(), 0); >> + >> + // Figure out how large the first NewMBB is. >> + unsigned NewBBSize = 0; >> + for (MachineBasicBlock::iterator I = NewBB->begin(), E = NewBB- >> >end(); >> + I != E; ++I) >> + NewBBSize += TII->GetInstSizeInBytes(I); >> + >> + unsigned NewBBI = NewBB->getNumber(); >> + unsigned JTBBI = JTBB->getNumber(); >> + // Set the size of NewBB in BBSizes. >> + BBSizes[NewBBI] = NewBBSize; >> + >> + // ...and adjust BBOffsets for NewBB accordingly. >> + BBOffsets[NewBBI] = BBOffsets[JTBBI] + BBSizes[JTBBI]; >> + >> + // All BBOffsets following these blocks must be modified. >> + AdjustBBOffsetsAfter(NewBB, 4); >> + >> + ++NumJTMoved; >> + return NewBB; >> +} >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From sabre at nondot.org Wed Nov 11 11:37:02 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 17:37:02 -0000 Subject: [llvm-commits] [llvm] r86846 - /llvm/trunk/lib/VMCore/Verifier.cpp Message-ID: <200911111737.nABHb22o030209@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 11 11:37:02 2009 New Revision: 86846 URL: http://llvm.org/viewvc/llvm-project?rev=86846&view=rev Log: Reject duplicate case values in a switch, PR5450. Modified: llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=86846&r1=86845&r2=86846&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Wed Nov 11 11:37:02 2009 @@ -780,9 +780,13 @@ // Check to make sure that all of the constants in the switch instruction // have the same type as the switched-on value. const Type *SwitchTy = SI.getCondition()->getType(); - for (unsigned i = 1, e = SI.getNumCases(); i != e; ++i) + SmallPtrSet Constants; + for (unsigned i = 1, e = SI.getNumCases(); i != e; ++i) { Assert1(SI.getCaseValue(i)->getType() == SwitchTy, "Switch constants must all be same type as switch value!", &SI); + Assert2(Constants.insert(SI.getCaseValue(i)), + "Duplicate integer as switch case", &SI, SI.getCaseValue(i)); + } visitTerminatorInst(SI); } From bob.wilson at apple.com Wed Nov 11 11:42:41 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 11 Nov 2009 09:42:41 -0800 Subject: [llvm-commits] [llvm] r86791 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp In-Reply-To: References: <200911110247.nAB2lJjM014802@zion.cs.uiuc.edu> <90A068C9-E8C3-4C2D-B186-838F68F053C0@apple.com> Message-ID: <41DF73EA-6ED0-44BB-9084-D8366E11A928@apple.com> On Nov 11, 2009, at 9:22 AM, Jim Grosbach wrote: > > Why was the code placement opt unsafe for arm before? I don't recall > the history there. If I remember correctly, it was running after ARMConstantIslandPass when it is not safe to change the size or position of anything. From sabre at nondot.org Wed Nov 11 11:51:27 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 17:51:27 -0000 Subject: [llvm-commits] [llvm] r86847 - /llvm/trunk/lib/Target/README.txt Message-ID: <200911111751.nABHpRGM030746@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 11 11:51:27 2009 New Revision: 86847 URL: http://llvm.org/viewvc/llvm-project?rev=86847&view=rev Log: add a note Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=86847&r1=86846&r2=86847&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Wed Nov 11 11:51:27 2009 @@ -1682,3 +1682,31 @@ } //===---------------------------------------------------------------------===// + +IPSCCP does not currently propagate argument dependent constants through +functions where it does not not all of the callers. This includes functions +with normal external linkage as well as templates, C99 inline functions etc. +Specifically, it does nothing to: + +define i32 @test(i32 %x, i32 %y, i32 %z) nounwind { +entry: + %0 = add nsw i32 %y, %z + %1 = mul i32 %0, %x + %2 = mul i32 %y, %z + %3 = add nsw i32 %1, %2 + ret i32 %3 +} + +define i32 @test2() nounwind { +entry: + %0 = call i32 @test(i32 1, i32 2, i32 4) nounwind + ret i32 %0 +} + +It would be interesting extend IPSCCP to be able to handle simple cases like +this, where all of the arguments to a call are constant. Because IPSCCP runs +before inlining, trivial templates and inline functions are not yet inlined. +The results for a function + set of constant arguments should be memoized in a +map. + +//===---------------------------------------------------------------------===// From sabre at nondot.org Wed Nov 11 11:54:02 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 17:54:02 -0000 Subject: [llvm-commits] [llvm] r86848 - /llvm/trunk/lib/Target/README.txt Message-ID: <200911111754.nABHs2Wn030824@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 11 11:54:02 2009 New Revision: 86848 URL: http://llvm.org/viewvc/llvm-project?rev=86848&view=rev Log: another const prop failure. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=86848&r1=86847&r2=86848&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Wed Nov 11 11:54:02 2009 @@ -1710,3 +1710,12 @@ map. //===---------------------------------------------------------------------===// + +The libcall constant folding stuff should be moved out of SimplifyLibcalls into +libanalysis' constantfolding logic. This would allow IPSCCP to be able to +handle simple things like this: + +static int foo(const char *X) { return strlen(X); } +int bar() { return foo("abcd"); } + +//===---------------------------------------------------------------------===// From gohman at apple.com Wed Nov 11 12:07:16 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 11 Nov 2009 18:07:16 -0000 Subject: [llvm-commits] [llvm] r86850 - /llvm/trunk/lib/Target/X86/X86InstrInfo.td Message-ID: <200911111807.nABI7HVm031305@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 11 12:07:16 2009 New Revision: 86850 URL: http://llvm.org/viewvc/llvm-project?rev=86850&view=rev Log: Use a tab in INT3's asm string, for consistency. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=86850&r1=86849&r2=86850&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed Nov 11 12:07:16 2009 @@ -543,7 +543,7 @@ } // Trap -def INT3 : I<0xcc, RawFrm, (outs), (ins), "int 3", []>; +def INT3 : I<0xcc, RawFrm, (outs), (ins), "int\t3", []>; def INT : I<0xcd, RawFrm, (outs), (ins i8imm:$trap), "int\t$trap", []>; // PIC base construction. This expands to code that looks like this: From gohman at apple.com Wed Nov 11 12:11:07 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 11 Nov 2009 18:11:07 -0000 Subject: [llvm-commits] [llvm] r86851 - in /llvm/trunk/lib/Target: Alpha/AlphaInstrInfo.td Blackfin/BlackfinInstrInfo.td MSP430/MSP430InstrInfo.td Sparc/SparcInstrInfo.td XCore/XCoreInstrInfo.td Message-ID: <200911111811.nABIB7iT031446@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 11 12:11:07 2009 New Revision: 86851 URL: http://llvm.org/viewvc/llvm-project?rev=86851&view=rev Log: Set isBarrier = 1 on return instructions, as they are control barriers. Modified: llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td Modified: llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td?rev=86851&r1=86850&r2=86851&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td (original) +++ llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td Wed Nov 11 12:11:07 2009 @@ -391,7 +391,7 @@ def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>; -let isReturn = 1, isTerminator = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in { +let isReturn = 1, isTerminator = 1, isBarrier = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in { def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", s_jsr>; //Return from subroutine def RETDAGp : MbrpForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", [(retflag)], s_jsr>; //Return from subroutine } Modified: llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td?rev=86851&r1=86850&r2=86851&view=diff ============================================================================== --- llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td (original) +++ llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td Wed Nov 11 12:11:07 2009 @@ -174,6 +174,7 @@ let isReturn = 1, isTerminator = 1, + isBarrier = 1, Uses = [RETS] in def RTS: F1<(outs), (ins), "rts;", [(BfinRet)]>; Modified: llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td?rev=86851&r1=86850&r2=86851&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td (original) +++ llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td Wed Nov 11 12:11:07 2009 @@ -127,7 +127,7 @@ // // FIXME: Provide proper encoding! -let isReturn = 1, isTerminator = 1 in { +let isReturn = 1, isTerminator = 1, isBarrier = 1 in { def RET : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>; } Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td?rev=86851&r1=86850&r2=86851&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td (original) +++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td Wed Nov 11 12:11:07 2009 @@ -277,7 +277,7 @@ // Section A.3 - Synthetic Instructions, p. 85 // special cases of JMPL: -let isReturn = 1, isTerminator = 1, hasDelaySlot = 1 in { +let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1 in { let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in def RETL: F3_2<2, 0b111000, (outs), (ins), "retl", [(retflag)]>; } Modified: llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td?rev=86851&r1=86850&r2=86851&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td (original) +++ llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td Wed Nov 11 12:11:07 2009 @@ -617,7 +617,7 @@ let mayStore = 1 in defm ENTSP : FU6_LU6_np<"entsp">; -let isReturn = 1, isTerminator = 1, mayLoad = 1 in { +let isReturn = 1, isTerminator = 1, mayLoad = 1, isBarrier = 1 in { defm RETSP : FU6_LU6<"retsp", XCoreRetsp>; } } From gohman at apple.com Wed Nov 11 12:14:02 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 11 Nov 2009 18:14:02 -0000 Subject: [llvm-commits] [llvm] r86852 - /llvm/trunk/include/llvm/Analysis/CFGPrinter.h Message-ID: <200911111814.nABIE2P7031538@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 11 12:14:02 2009 New Revision: 86852 URL: http://llvm.org/viewvc/llvm-project?rev=86852&view=rev Log: Fix a copy+pasto in a comment. Modified: llvm/trunk/include/llvm/Analysis/CFGPrinter.h Modified: llvm/trunk/include/llvm/Analysis/CFGPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/CFGPrinter.h?rev=86852&r1=86851&r2=86852&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/CFGPrinter.h (original) +++ llvm/trunk/include/llvm/Analysis/CFGPrinter.h Wed Nov 11 12:14:02 2009 @@ -72,7 +72,7 @@ if (BI->isConditional()) return (I == succ_begin(Node)) ? "T" : "F"; - // Label source of conditional branches with "T" or "F" + // Label source of switch edges with the associated value. if (const SwitchInst *SI = dyn_cast(Node->getTerminator())) { unsigned SuccNo = I.getSuccessorIndex(); From gohman at apple.com Wed Nov 11 12:18:34 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 11 Nov 2009 18:18:34 -0000 Subject: [llvm-commits] [llvm] r86853 - /llvm/trunk/lib/CodeGen/BranchFolding.cpp Message-ID: <200911111818.nABIIYKj031717@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 11 12:18:34 2009 New Revision: 86853 URL: http://llvm.org/viewvc/llvm-project?rev=86853&view=rev Log: Minor code simplification. Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=86853&r1=86852&r2=86853&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Wed Nov 11 12:18:34 2009 @@ -875,6 +875,7 @@ /// block. This is never called on the entry block. bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { bool MadeChange = false; + MachineFunction &MF = *MBB->getParent(); MachineFunction::iterator FallThrough = MBB; ++FallThrough; @@ -887,7 +888,7 @@ // Dead block? Leave for cleanup later. if (MBB->pred_empty()) return MadeChange; - if (FallThrough == MBB->getParent()->end()) { + if (FallThrough == MF.end()) { // TODO: Simplify preds to not branch here if possible! } else { // Rewrite all predecessors of the old block to go to the fallthrough @@ -898,8 +899,7 @@ } // If MBB was the target of a jump table, update jump tables to go to the // fallthrough instead. - MBB->getParent()->getJumpTableInfo()-> - ReplaceMBBInJumpTables(MBB, FallThrough); + MF.getJumpTableInfo()->ReplaceMBBInJumpTables(MBB, FallThrough); MadeChange = true; } return MadeChange; @@ -982,7 +982,7 @@ // last block in the function, we'd just keep swapping the two blocks for // last. Only do the swap if one is clearly better to fall through than // the other. - if (FallThrough == --MBB->getParent()->end() && + if (FallThrough == --MF.end() && !IsBetterFallthrough(PriorTBB, MBB)) DoTransform = false; @@ -1013,7 +1013,7 @@ TII->InsertBranch(PrevBB, MBB, 0, NewPriorCond); // Move this block to the end of the function. - MBB->moveAfter(--MBB->getParent()->end()); + MBB->moveAfter(--MF.end()); MadeChange = true; ++NumBranchOpts; return MadeChange; @@ -1114,8 +1114,7 @@ } // Change any jumptables to go to the new MBB. - MBB->getParent()->getJumpTableInfo()-> - ReplaceMBBInJumpTables(MBB, CurTBB); + MF.getJumpTableInfo()->ReplaceMBBInJumpTables(MBB, CurTBB); if (DidChange) { ++NumBranchOpts; MadeChange = true; @@ -1195,9 +1194,9 @@ // Okay, there is no really great place to put this block. If, however, // the block before this one would be a fall-through if this block were // removed, move this block to the end of the function. - if (FallThrough != MBB->getParent()->end() && + if (FallThrough != MF.end() && PrevBB.isSuccessor(FallThrough)) { - MBB->moveAfter(--MBB->getParent()->end()); + MBB->moveAfter(--MF.end()); MadeChange = true; return MadeChange; } From gohman at apple.com Wed Nov 11 12:23:18 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 11 Nov 2009 18:23:18 -0000 Subject: [llvm-commits] [llvm] r86854 - /llvm/trunk/lib/CodeGen/BranchFolding.cpp Message-ID: <200911111823.nABINJQB031895@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 11 12:23:17 2009 New Revision: 86854 URL: http://llvm.org/viewvc/llvm-project?rev=86854&view=rev Log: Prefix MBB numbers with "BB#" in debug output to make it clear what the numbers mean. Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=86854&r1=86853&r2=86854&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Wed Nov 11 12:23:17 2009 @@ -562,7 +562,7 @@ MachineBasicBlock::iterator BBI = SameTails[commonTailIndex].second; MachineBasicBlock *MBB = SameTails[commonTailIndex].first->second; - DEBUG(errs() << "\nSplitting " << MBB->getNumber() << ", size " + DEBUG(errs() << "\nSplitting BB#" << MBB->getNumber() << ", size " << maxCommonTailLength); MachineBasicBlock *newMBB = SplitMBBAt(*MBB, BBI); @@ -639,11 +639,11 @@ MachineBasicBlock *MBB = SameTails[commonTailIndex].first->second; // MBB is common tail. Adjust all other BB's to jump to this one. // Traversal must be forwards so erases work. - DEBUG(errs() << "\nUsing common tail " << MBB->getNumber() << " for "); + DEBUG(errs() << "\nUsing common tail BB#" << MBB->getNumber() << " for "); for (unsigned int i=0; isecond->getNumber() << ","); + DEBUG(errs() << "BB#" << SameTails[i].first->second->getNumber() << ", "); // Hack the end off BB i, making it jump to BB commonTailIndex instead. ReplaceTailWithBranchTo(SameTails[i].second, MBB); // BB i is no longer a predecessor of SuccBB; remove it from the worklist. From gohman at apple.com Wed Nov 11 12:31:05 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 11 Nov 2009 10:31:05 -0800 Subject: [llvm-commits] sret-demotion for large struct returns working on x86! In-Reply-To: <400d33ea0911091842i262ebf40t5a39731c6c3de7a7@mail.gmail.com> References: <400d33ea0911081837t48a2447bw7ace6c45c41e8f2@mail.gmail.com> <5CC43A6B-57E4-42A7-B1E6-CCD9875F65D7@apple.com> <400d33ea0911091343w1549702enbbbb0c7b34b75cfa@mail.gmail.com> <400d33ea0911091842i262ebf40t5a39731c6c3de7a7@mail.gmail.com> Message-ID: <5F9E6E75-1386-4FB5-9F71-E167180FB684@apple.com> On Nov 9, 2009, at 6:42 PM, Kenneth Uildriks wrote: > Here's the updated version of the patch: > > 1. Moved the flag and demote register from MachineFunction to > FunctionLoweringInfo > 2. Inverted CantLowerReturn to CanLowerReturn while carrying out #1 > 3. Now passing the return Attributes to getReturnInfo and using its > ZExt and SExt flags properly. > 4. Cleaned up braces. Looks good, thanks! Dan From gohman at apple.com Wed Nov 11 12:38:14 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 11 Nov 2009 18:38:14 -0000 Subject: [llvm-commits] [llvm] r86855 - /llvm/trunk/lib/CodeGen/BranchFolding.cpp Message-ID: <200911111838.nABIcFjo032372@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 11 12:38:14 2009 New Revision: 86855 URL: http://llvm.org/viewvc/llvm-project?rev=86855&view=rev Log: Whitespace cleanups. Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=86855&r1=86854&r2=86855&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Wed Nov 11 12:38:14 2009 @@ -40,18 +40,18 @@ STATISTIC(NumDeadBlocks, "Number of dead blocks removed"); STATISTIC(NumBranchOpts, "Number of branches optimized"); STATISTIC(NumTailMerge , "Number of block tails merged"); -static cl::opt FlagEnableTailMerge("enable-tail-merge", +static cl::opt FlagEnableTailMerge("enable-tail-merge", cl::init(cl::BOU_UNSET), cl::Hidden); // Throttle for huge numbers of predecessors (compile speed problems) static cl::opt -TailMergeThreshold("tail-merge-threshold", +TailMergeThreshold("tail-merge-threshold", cl::desc("Max number of predecessors to consider tail merging"), cl::init(150), cl::Hidden); char BranchFolderPass::ID = 0; -FunctionPass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge) { +FunctionPass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge) { return new BranchFolderPass(DefaultEnableTailMerge); } @@ -63,7 +63,6 @@ } - BranchFolder::BranchFolder(bool defaultEnableTailMerge) { switch (FlagEnableTailMerge) { case cl::BOU_UNSET: EnableTailMerge = defaultEnableTailMerge; break; @@ -77,12 +76,12 @@ void BranchFolder::RemoveDeadBlock(MachineBasicBlock *MBB) { assert(MBB->pred_empty() && "MBB must be dead!"); DEBUG(errs() << "\nRemoving MBB: " << *MBB); - + MachineFunction *MF = MBB->getParent(); // drop all successors. while (!MBB->succ_empty()) MBB->removeSuccessor(MBB->succ_end()-1); - + // If there are any labels in the basic block, unregister them from // MachineModuleInfo. if (MMI && !MBB->empty()) { @@ -93,7 +92,7 @@ MMI->InvalidateLabel(I->getOperand(0).getImm()); } } - + // Remove the block. MF->erase(MBB); } @@ -190,7 +189,7 @@ // Figure out how these jump tables should be merged. std::vector JTMapping; JTMapping.reserve(JTs.size()); - + // We always keep the 0th jump table. JTMapping.push_back(0); @@ -202,7 +201,7 @@ else JTMapping.push_back(JTI->getJumpTableIndex(JTs[i].MBBs)); } - + // If a jump table was merge with another one, walk the function rewriting // references to jump tables to reference the new JT ID's. Keep track of // whether we see a jump table idx, if not, we can delete the JT. @@ -221,7 +220,7 @@ JTIsLive.set(NewIdx); } } - + // Finally, remove dead jump tables. This happens either because the // indirect jump was unreachable (and thus deleted) or because the jump // table was merged with some other one. @@ -245,7 +244,7 @@ unsigned Hash = MI->getOpcode(); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &Op = MI->getOperand(i); - + // Merge in bits from the operand if easy. unsigned OperandHash = 0; switch (Op.getType()) { @@ -267,31 +266,30 @@ break; default: break; } - + Hash += ((OperandHash << 3) | Op.getType()) << (i&31); } return Hash; } /// HashEndOfMBB - Hash the last few instructions in the MBB. For blocks -/// with no successors, we hash two instructions, because cross-jumping -/// only saves code when at least two instructions are removed (since a +/// with no successors, we hash two instructions, because cross-jumping +/// only saves code when at least two instructions are removed (since a /// branch must be inserted). For blocks with a successor, one of the /// two blocks to be tail-merged will end with a branch already, so /// it gains to cross-jump even for one instruction. - static unsigned HashEndOfMBB(const MachineBasicBlock *MBB, unsigned minCommonTailLength) { MachineBasicBlock::const_iterator I = MBB->end(); if (I == MBB->begin()) return 0; // Empty MBB. - + --I; unsigned Hash = HashMachineInstr(I); - + if (I == MBB->begin() || minCommonTailLength == 1) return Hash; // Single instr MBB. - + --I; // Hash in the second-to-last instruction. Hash ^= HashMachineInstr(I) << 2; @@ -307,11 +305,11 @@ MachineBasicBlock::iterator &I2) { I1 = MBB1->end(); I2 = MBB2->end(); - + unsigned TailLen = 0; while (I1 != MBB1->begin() && I2 != MBB2->begin()) { --I1; --I2; - if (!I1->isIdenticalTo(I2) || + if (!I1->isIdenticalTo(I2) || // FIXME: This check is dubious. It's used to get around a problem where // people incorrectly expect inline asm directives to remain in the same // relative order. This is untenable because normal compiler @@ -332,11 +330,11 @@ void BranchFolder::ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, MachineBasicBlock *NewDest) { MachineBasicBlock *OldBB = OldInst->getParent(); - + // Remove all the old successors of OldBB from the CFG. while (!OldBB->succ_empty()) OldBB->removeSuccessor(OldBB->succ_begin()); - + // Remove all the dead instructions from the end of OldBB. OldBB->erase(OldInst, OldBB->end()); @@ -361,10 +359,10 @@ // Move all the successors of this block to the specified block. NewMBB->transferSuccessors(&CurMBB); - + // Add an edge from CurMBB to NewMBB for the fall-through. CurMBB.addSuccessor(NewMBB); - + // Splice the code over. NewMBB->splice(NewMBB->end(), &CurMBB, BBI1, CurMBB.end()); @@ -404,7 +402,6 @@ // branches temporarily for tail merging). In the case where CurMBB ends // with a conditional branch to the next block, optimize by reversing the // test and conditionally branching to SuccMBB instead. - static void FixTail(MachineBasicBlock* CurMBB, MachineBasicBlock *SuccBB, const TargetInstrInfo *TII) { MachineFunction *MF = CurMBB->getParent(); @@ -476,26 +473,26 @@ } /// ComputeSameTails - Look through all the blocks in MergePotentials that have -/// hash CurHash (guaranteed to match the last element). Build the vector +/// hash CurHash (guaranteed to match the last element). Build the vector /// SameTails of all those that have the (same) largest number of instructions /// in common of any pair of these blocks. SameTails entries contain an -/// iterator into MergePotentials (from which the MachineBasicBlock can be -/// found) and a MachineBasicBlock::iterator into that MBB indicating the +/// iterator into MergePotentials (from which the MachineBasicBlock can be +/// found) and a MachineBasicBlock::iterator into that MBB indicating the /// instruction where the matching code sequence begins. /// Order of elements in SameTails is the reverse of the order in which /// those blocks appear in MergePotentials (where they are not necessarily /// consecutive). -unsigned BranchFolder::ComputeSameTails(unsigned CurHash, +unsigned BranchFolder::ComputeSameTails(unsigned CurHash, unsigned minCommonTailLength) { unsigned maxCommonTailLength = 0U; SameTails.clear(); MachineBasicBlock::iterator TrialBBI1, TrialBBI2; MPIterator HighestMPIter = prior(MergePotentials.end()); for (MPIterator CurMPIter = prior(MergePotentials.end()), - B = MergePotentials.begin(); - CurMPIter!=B && CurMPIter->first==CurHash; + B = MergePotentials.begin(); + CurMPIter!=B && CurMPIter->first == CurHash; --CurMPIter) { - for (MPIterator I = prior(CurMPIter); I->first==CurHash ; --I) { + for (MPIterator I = prior(CurMPIter); I->first == CurHash ; --I) { unsigned CommonTailLen; if (ProfitableToMerge(CurMPIter->second, I->second, minCommonTailLength, CommonTailLen, TrialBBI1, TrialBBI2)) { @@ -509,7 +506,7 @@ CommonTailLen == maxCommonTailLength) SameTails.push_back(std::make_pair(I, TrialBBI2)); } - if (I==B) + if (I == B) break; } } @@ -518,18 +515,18 @@ /// RemoveBlocksWithHash - Remove all blocks with hash CurHash from /// MergePotentials, restoring branches at ends of blocks as appropriate. -void BranchFolder::RemoveBlocksWithHash(unsigned CurHash, +void BranchFolder::RemoveBlocksWithHash(unsigned CurHash, MachineBasicBlock* SuccBB, MachineBasicBlock* PredBB) { MPIterator CurMPIter, B; - for (CurMPIter = prior(MergePotentials.end()), B = MergePotentials.begin(); - CurMPIter->first==CurHash; + for (CurMPIter = prior(MergePotentials.end()), B = MergePotentials.begin(); + CurMPIter->first == CurHash; --CurMPIter) { // Put the unconditional branch back, if we need one. MachineBasicBlock *CurMBB = CurMPIter->second; if (SuccBB && CurMBB != PredBB) FixTail(CurMBB, SuccBB, TII); - if (CurMPIter==B) + if (CurMPIter == B) break; } if (CurMPIter->first!=CurHash) @@ -545,15 +542,15 @@ unsigned TimeEstimate = ~0U; for (i=0, commonTailIndex=0; isecond==PredBB) { + if (SameTails[i].first->second == PredBB) { commonTailIndex = i; break; } // Otherwise, make a (fairly bogus) choice based on estimate of // how long it will take the various blocks to execute. - unsigned t = EstimateRuntime(SameTails[i].first->second->begin(), + unsigned t = EstimateRuntime(SameTails[i].first->second->begin(), SameTails[i].second); - if (t<=TimeEstimate) { + if (t <= TimeEstimate) { TimeEstimate = t; commonTailIndex = i; } @@ -568,8 +565,9 @@ MachineBasicBlock *newMBB = SplitMBBAt(*MBB, BBI); SameTails[commonTailIndex].first->second = newMBB; SameTails[commonTailIndex].second = newMBB->begin(); + // If we split PredBB, newMBB is the new predecessor. - if (PredBB==MBB) + if (PredBB == MBB) PredBB = newMBB; return commonTailIndex; @@ -579,7 +577,7 @@ // successor, or all have no successor) can be tail-merged. If there is a // successor, any blocks in MergePotentials that are not tail-merged and // are not immediately before Succ must have an unconditional branch to -// Succ added (but the predecessor/successor lists need no adjustment). +// Succ added (but the predecessor/successor lists need no adjustment). // The lone predecessor of Succ that falls through into Succ, // if any, is given in PredBB. @@ -591,7 +589,7 @@ // will add a jump. // FIXME: Ask the target to provide the threshold? unsigned minCommonTailLength = (SuccBB ? 1 : 2) + 1; - + DEBUG(errs() << "\nTryMergeBlocks " << MergePotentials.size() << '\n'); // Sort by hash value so that blocks with identical end sequences sort @@ -601,13 +599,13 @@ // Walk through equivalence sets looking for actual exact matches. while (MergePotentials.size() > 1) { unsigned CurHash = MergePotentials.back().first; - + // Build SameTails, identifying the set of blocks with this hash code // and with the maximum number of instructions in common. - unsigned maxCommonTailLength = ComputeSameTails(CurHash, + unsigned maxCommonTailLength = ComputeSameTails(CurHash, minCommonTailLength); - // If we didn't find any pair that has at least minCommonTailLength + // If we didn't find any pair that has at least minCommonTailLength // instructions in common, remove all blocks with this hash code and retry. if (SameTails.empty()) { RemoveBlocksWithHash(CurHash, SuccBB, PredBB); @@ -625,12 +623,12 @@ MachineBasicBlock *MBB = SameTails[i].first->second; if (MBB->begin() == SameTails[i].second && MBB != EntryBB) { commonTailIndex = i; - if (MBB==PredBB) + if (MBB == PredBB) break; } } - if (commonTailIndex==SameTails.size()) { + if (commonTailIndex == SameTails.size()) { // None of the blocks consist entirely of the common tail. // Split a block so that one does. commonTailIndex = CreateCommonTailOnlyBlock(PredBB, maxCommonTailLength); @@ -641,7 +639,7 @@ // Traversal must be forwards so erases work. DEBUG(errs() << "\nUsing common tail BB#" << MBB->getNumber() << " for "); for (unsigned int i=0; isecond->getNumber() << ", "); // Hack the end off BB i, making it jump to BB commonTailIndex instead. @@ -660,7 +658,7 @@ bool BranchFolder::TailMergeBlocks(MachineFunction &MF) { if (!EnableTailMerge) return false; - + bool MadeChange = false; // First find blocks with no successors. @@ -669,6 +667,7 @@ if (I->succ_empty()) MergePotentials.push_back(std::make_pair(HashEndOfMBB(I, 2U), I)); } + // See if we can do any tail merging on those. if (MergePotentials.size() < TailMergeThreshold && MergePotentials.size() >= 2) @@ -679,7 +678,7 @@ // (1) temporarily removing any unconditional branch from the predecessor // to IBB, and // (2) alter conditional branches so they branch to the other block - // not IBB; this may require adding back an unconditional branch to IBB + // not IBB; this may require adding back an unconditional branch to IBB // later, where there wasn't one coming in. E.g. // Bcc IBB // fallthrough to QBB @@ -699,12 +698,12 @@ MachineBasicBlock *IBB = I; MachineBasicBlock *PredBB = prior(I); MergePotentials.clear(); - for (MachineBasicBlock::pred_iterator P = I->pred_begin(), + for (MachineBasicBlock::pred_iterator P = I->pred_begin(), E2 = I->pred_end(); P != E2; ++P) { MachineBasicBlock* PBB = *P; // Skip blocks that loop to themselves, can't tail merge these. - if (PBB==IBB) + if (PBB == IBB) continue; // Visit each predecessor only once. if (!UniquePreds.insert(PBB)) @@ -715,7 +714,7 @@ // Failing case: IBB is the target of a cbr, and // we cannot reverse the branch. SmallVector NewCond(Cond); - if (!Cond.empty() && TBB==IBB) { + if (!Cond.empty() && TBB == IBB) { if (TII->ReverseBranchCondition(NewCond)) continue; // This is the QBB case described above @@ -730,7 +729,7 @@ MachineBasicBlock* PredNextBB = NULL; if (IP!=MF.end()) PredNextBB = IP; - if (TBB==NULL) { + if (TBB == NULL) { if (IBB!=PredNextBB) // fallthrough continue; } else if (FBB) { @@ -749,7 +748,7 @@ TII->RemoveBranch(*PBB); if (!Cond.empty()) // reinsert conditional branch only, for now - TII->InsertBranch(*PBB, (TBB==IBB) ? FBB : TBB, 0, NewCond); + TII->InsertBranch(*PBB, (TBB == IBB) ? FBB : TBB, 0, NewCond); } MergePotentials.push_back(std::make_pair(HashEndOfMBB(PBB, 1U), *P)); } @@ -759,7 +758,7 @@ // Reinsert an unconditional branch if needed. // The 1 below can occur as a result of removing blocks in TryMergeBlocks. PredBB = prior(I); // this may have been changed in TryMergeBlocks - if (MergePotentials.size()==1 && + if (MergePotentials.size() == 1 && MergePotentials.begin()->second != PredBB) FixTail(MergePotentials.begin()->second, I, TII); } @@ -773,14 +772,14 @@ bool BranchFolder::OptimizeBranches(MachineFunction &MF) { bool MadeChange = false; - + // Make sure blocks are numbered in order MF.RenumberBlocks(); for (MachineFunction::iterator I = ++MF.begin(), E = MF.end(); I != E; ) { MachineBasicBlock *MBB = I++; MadeChange |= OptimizeBlock(MBB); - + // If it is dead, remove it. if (MBB->pred_empty()) { RemoveDeadBlock(MBB); @@ -801,7 +800,7 @@ /// bool BranchFolder::CanFallThrough(MachineBasicBlock *CurBB, bool BranchUnAnalyzable, - MachineBasicBlock *TBB, + MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl &Cond) { MachineFunction::iterator Fallthrough = CurBB; @@ -809,14 +808,14 @@ // If FallthroughBlock is off the end of the function, it can't fall through. if (Fallthrough == CurBB->getParent()->end()) return false; - + // If FallthroughBlock isn't a successor of CurBB, no fallthrough is possible. if (!CurBB->isSuccessor(Fallthrough)) return false; - + // If we couldn't analyze the branch, assume it could fall through. if (BranchUnAnalyzable) return true; - + // If there is no branch, control always falls through. if (TBB == 0) return true; @@ -825,11 +824,11 @@ if (MachineFunction::iterator(TBB) == Fallthrough || MachineFunction::iterator(FBB) == Fallthrough) return true; - - // If it's an unconditional branch to some block not the fall through, it + + // If it's an unconditional branch to some block not the fall through, it // doesn't fall through. if (Cond.empty()) return false; - + // Otherwise, if it is conditional and has no explicit false block, it falls // through. return FBB == 0; @@ -853,14 +852,14 @@ /// fall-through to MBB1 than to fall through into MBB2. This has to return /// a strict ordering, returning true for both (MBB1,MBB2) and (MBB2,MBB1) will /// result in infinite loops. -static bool IsBetterFallthrough(MachineBasicBlock *MBB1, +static bool IsBetterFallthrough(MachineBasicBlock *MBB1, MachineBasicBlock *MBB2) { // Right now, we use a simple heuristic. If MBB2 ends with a call, and // MBB1 doesn't, we prefer to fall through into MBB1. This allows us to // optimize branches that branch to either a return block or an assert block // into a fallthrough to the return. if (MBB1->empty() || MBB2->empty()) return false; - + // If there is a clear successor ordering we make sure that one block // will fall through to the next if (MBB1->isSuccessor(MBB2)) return true; @@ -879,7 +878,7 @@ MachineFunction::iterator FallThrough = MBB; ++FallThrough; - + // If this block is empty, make everyone use its fall-through, not the block // explicitly. Landing pads should not do this since the landing-pad table // points to this block. Blocks with their addresses taken shouldn't be @@ -887,7 +886,7 @@ if (MBB->empty() && !MBB->isLandingPad() && !MBB->hasAddressTaken()) { // Dead block? Leave for cleanup later. if (MBB->pred_empty()) return MadeChange; - + if (FallThrough == MF.end()) { // TODO: Simplify preds to not branch here if possible! } else { @@ -917,20 +916,20 @@ // If the CFG for the prior block has extra edges, remove them. MadeChange |= PrevBB.CorrectExtraCFGEdges(PriorTBB, PriorFBB, !PriorCond.empty()); - + // If the previous branch is conditional and both conditions go to the same // destination, remove the branch, replacing it with an unconditional one or // a fall-through. if (PriorTBB && PriorTBB == PriorFBB) { TII->RemoveBranch(PrevBB); - PriorCond.clear(); + PriorCond.clear(); if (PriorTBB != MBB) TII->InsertBranch(PrevBB, PriorTBB, 0, PriorCond); MadeChange = true; ++NumBranchOpts; return OptimizeBlock(MBB); } - + // If the previous branch *only* branches to *this* block (conditional or // not) remove the branch. if (PriorTBB == MBB && PriorFBB == 0) { @@ -939,7 +938,7 @@ ++NumBranchOpts; return OptimizeBlock(MBB); } - + // If the prior block branches somewhere else on the condition and here if // the condition is false, remove the uncond second branch. if (PriorFBB == MBB) { @@ -949,7 +948,7 @@ ++NumBranchOpts; return OptimizeBlock(MBB); } - + // If the prior block branches here on true and somewhere else on false, and // if the branch condition is reversible, reverse the branch to create a // fall-through. @@ -963,7 +962,7 @@ return OptimizeBlock(MBB); } } - + // If this block has no successors (e.g. it is a return block or ends with // a call to a no-return function like abort or __cxa_throw) and if the pred // falls through into this block, and if it would otherwise fall through @@ -976,7 +975,7 @@ MachineFunction::iterator(PriorTBB) == FallThrough && !CanFallThrough(MBB)) { bool DoTransform = true; - + // We have to be careful that the succs of PredBB aren't both no-successor // blocks. If neither have successors and if PredBB is the second from // last block in the function, we'd just keep swapping the two blocks for @@ -1000,15 +999,15 @@ if (DoTransform && !MBB->succ_empty() && (!CanFallThrough(PriorTBB) || PriorTBB->empty())) DoTransform = false; - - + + if (DoTransform) { // Reverse the branch so we will fall through on the previous true cond. SmallVector NewPriorCond(PriorCond); if (!TII->ReverseBranchCondition(NewPriorCond)) { DEBUG(errs() << "\nMoving MBB: " << *MBB << "To make fallthrough to: " << *PriorTBB << "\n"); - + TII->RemoveBranch(PrevBB); TII->InsertBranch(PrevBB, MBB, 0, NewPriorCond); @@ -1021,7 +1020,7 @@ } } } - + // Analyze the branch in the current block. MachineBasicBlock *CurTBB = 0, *CurFBB = 0; SmallVector CurCond; @@ -1030,7 +1029,7 @@ // If the CFG for the prior block has extra edges, remove them. MadeChange |= MBB->CorrectExtraCFGEdges(CurTBB, CurFBB, !CurCond.empty()); - // If this is a two-way branch, and the FBB branches to this block, reverse + // If this is a two-way branch, and the FBB branches to this block, reverse // the condition so the single-basic-block loop is faster. Instead of: // Loop: xxx; jcc Out; jmp Loop // we want: @@ -1045,11 +1044,11 @@ return OptimizeBlock(MBB); } } - - + + // If this branch is the only thing in its block, see if we can forward // other blocks across it. - if (CurTBB && CurCond.empty() && CurFBB == 0 && + if (CurTBB && CurCond.empty() && CurFBB == 0 && MBB->begin()->getDesc().isBranch() && CurTBB != MBB && !MBB->hasAddressTaken()) { // This block may contain just an unconditional branch. Because there can @@ -1068,7 +1067,7 @@ !PrevBB.isSuccessor(MBB)) { // If the prior block falls through into us, turn it into an // explicit branch to us to make updates simpler. - if (!PredHasNoFallThrough && PrevBB.isSuccessor(MBB) && + if (!PredHasNoFallThrough && PrevBB.isSuccessor(MBB) && PriorTBB != MBB && PriorFBB != MBB) { if (PriorTBB == 0) { assert(PriorCond.empty() && PriorFBB == 0 && @@ -1104,7 +1103,7 @@ NewCurFBB, NewCurCond, true); if (!NewCurUnAnalyzable && NewCurTBB && NewCurTBB == NewCurFBB) { TII->RemoveBranch(*PMBB); - NewCurCond.clear(); + NewCurCond.clear(); TII->InsertBranch(*PMBB, NewCurTBB, 0, NewCurCond); MadeChange = true; ++NumBranchOpts; @@ -1122,7 +1121,7 @@ } } } - + // Add the branch back if the block is more than just an uncond branch. TII->InsertBranch(*MBB, CurTBB, 0, CurCond); } @@ -1135,7 +1134,7 @@ PriorTBB, PriorFBB, PriorCond)) { // Now we know that there was no fall-through into this block, check to // see if it has a fall-through into its successor. - bool CurFallsThru = CanFallThrough(MBB, CurUnAnalyzable, CurTBB, CurFBB, + bool CurFallsThru = CanFallThrough(MBB, CurUnAnalyzable, CurTBB, CurFBB, CurCond); if (!MBB->isLandingPad()) { @@ -1151,7 +1150,7 @@ && (!CurFallsThru || MBB->getNumber() >= PredBB->getNumber())) { // If the current block doesn't fall through, just move it. // If the current block can fall through and does not end with a - // conditional branch, we need to append an unconditional jump to + // conditional branch, we need to append an unconditional jump to // the (current) next block. To avoid a possible compile-time // infinite loop, move blocks only backward in this case. // Also, if there are already 2 branches here, we cannot add a third; @@ -1170,7 +1169,7 @@ } } } - + if (!CurFallsThru) { // Check all successors to see if we can move this block before it. for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), @@ -1178,7 +1177,7 @@ // Analyze the branch at the end of the block before the succ. MachineBasicBlock *SuccBB = *SI; MachineFunction::iterator SuccPrev = SuccBB; --SuccPrev; - + // If this block doesn't already fall-through to that successor, and if // the succ doesn't already have a block that can fall through into it, // and if the successor isn't an EH destination, we can arrange for the @@ -1190,7 +1189,7 @@ return OptimizeBlock(MBB); } } - + // Okay, there is no really great place to put this block. If, however, // the block before this one would be a fall-through if this block were // removed, move this block to the end of the function. From gohman at apple.com Wed Nov 11 12:42:28 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 11 Nov 2009 18:42:28 -0000 Subject: [llvm-commits] [llvm] r86856 - /llvm/trunk/lib/CodeGen/BranchFolding.cpp Message-ID: <200911111842.nABIgSTa032532@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 11 12:42:28 2009 New Revision: 86856 URL: http://llvm.org/viewvc/llvm-project?rev=86856&view=rev Log: Fix indentation level. Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=86856&r1=86855&r2=86856&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Wed Nov 11 12:42:28 2009 @@ -753,14 +753,14 @@ MergePotentials.push_back(std::make_pair(HashEndOfMBB(PBB, 1U), *P)); } } - if (MergePotentials.size() >= 2) - MadeChange |= TryMergeBlocks(I, PredBB); - // Reinsert an unconditional branch if needed. - // The 1 below can occur as a result of removing blocks in TryMergeBlocks. - PredBB = prior(I); // this may have been changed in TryMergeBlocks - if (MergePotentials.size() == 1 && - MergePotentials.begin()->second != PredBB) - FixTail(MergePotentials.begin()->second, I, TII); + if (MergePotentials.size() >= 2) + MadeChange |= TryMergeBlocks(I, PredBB); + // Reinsert an unconditional branch if needed. + // The 1 below can occur as a result of removing blocks in TryMergeBlocks. + PredBB = prior(I); // this may have been changed in TryMergeBlocks + if (MergePotentials.size() == 1 && + MergePotentials.begin()->second != PredBB) + FixTail(MergePotentials.begin()->second, I, TII); } } return MadeChange; From grosbach at apple.com Wed Nov 11 13:04:24 2009 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 11 Nov 2009 19:04:24 -0000 Subject: [llvm-commits] [llvm] r86857 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Message-ID: <200911111904.nABJ4OSE000833@zion.cs.uiuc.edu> Author: grosbach Date: Wed Nov 11 13:04:24 2009 New Revision: 86857 URL: http://llvm.org/viewvc/llvm-project?rev=86857&view=rev Log: Do jump table adjustment before constant island allocation Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=86857&r1=86856&r2=86857&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Wed Nov 11 13:04:24 2009 @@ -294,6 +294,11 @@ // sizes of each block, the location of all the water, and finding all of the // constant pool users. InitialFunctionScan(MF, CPEMIs); + + bool MadeChange = false; + if (isThumb2) + MadeChange |= OptimizeThumb2JumpTables(MF); + CPEMIs.clear(); /// Remove dead constant pool entries. @@ -301,7 +306,6 @@ // Iteratively place constant pool entries and fix up branches until there // is no change. - bool MadeChange = false; unsigned NoCPIters = 0, NoBRIters = 0; while (true) { bool CPChange = false; @@ -1476,7 +1480,6 @@ } MadeChange |= OptimizeThumb2Branches(MF); - MadeChange |= OptimizeThumb2JumpTables(MF); return MadeChange; } @@ -1722,8 +1725,8 @@ JTBB->addSuccessor(NewBB); // Update internal data structures to account for the newly inserted MBB. - // This is almost the same as UpdateForInsertedWaterBlock, except that - // the Water goes after OrigBB, not NewBB. + // Don't mark the new block as having water following it, as we want the + // blocks following the jump table to be as close together as possible. MF.RenumberBlocks(NewBB); // Insert a size into BBSizes to align it properly with the (newly From evan.cheng at apple.com Wed Nov 11 13:05:53 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 11 Nov 2009 19:05:53 -0000 Subject: [llvm-commits] [llvm] r86858 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h Message-ID: <200911111905.nABJ5rXi000907@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 11 13:05:52 2009 New Revision: 86858 URL: http://llvm.org/viewvc/llvm-project?rev=86858&view=rev Log: Add TargetLowering::isLegalICmpImmediate. It tells LSR what immediate can be folded into target icmp instructions. Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=86858&r1=86857&r2=86858&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Wed Nov 11 13:05:52 2009 @@ -1514,6 +1514,14 @@ return false; } + /// isLegalICmpImmediate - Return true if the specified immediate is legal + /// icmp immediate, that is the target has icmp instructions which can compare + /// a register against the immediate without having to materialize the + /// immediate into a register. + virtual bool isLegalICmpImmediate(uint64_t Imm) const { + return true; + } + //===--------------------------------------------------------------------===// // Div utility functions // Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=86858&r1=86857&r2=86858&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Nov 11 13:05:52 2009 @@ -3706,6 +3706,18 @@ return true; } +/// isLegalICmpImmediate - Return true if the specified immediate is legal +/// icmp immediate, that is the target has icmp instructions which can compare +/// a register against the immediate without having to materialize the +/// immediate into a register. +bool ARMTargetLowering::isLegalICmpImmediate(uint64_t Imm) const { + if (!Subtarget->isThumb()) + return ARM_AM::getSOImmVal(Imm) != -1; + if (Subtarget->isThumb2()) + return ARM_AM::getT2SOImmVal(Imm) != -1; + return Imm < 256; +} + static bool getARMIndexedAddressParts(SDNode *Ptr, EVT VT, bool isSEXTLoad, SDValue &Base, SDValue &Offset, bool &isInc, Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=86858&r1=86857&r2=86858&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Wed Nov 11 13:05:52 2009 @@ -180,6 +180,12 @@ virtual bool isLegalAddressingMode(const AddrMode &AM, const Type *Ty)const; bool isLegalT2ScaledAddressingMode(const AddrMode &AM, EVT VT) const; + /// isLegalICmpImmediate - Return true if the specified immediate is legal + /// icmp immediate, that is the target has icmp instructions which can compare + /// a register against the immediate without having to materialize the + /// immediate into a register. + virtual bool isLegalICmpImmediate(uint64_t Imm) const; + /// getPreIndexedAddressParts - returns true by value, base pointer and /// offset pointer and addressing mode by reference if the node's address /// can be legally represented as pre-indexed load / store address. From dpatel at apple.com Wed Nov 11 13:06:06 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 11 Nov 2009 19:06:06 -0000 Subject: [llvm-commits] [llvm] r86859 - /llvm/trunk/include/llvm/Support/IRBuilder.h Message-ID: <200911111906.nABJ66Dt000926@zion.cs.uiuc.edu> Author: dpatel Date: Wed Nov 11 13:06:06 2009 New Revision: 86859 URL: http://llvm.org/viewvc/llvm-project?rev=86859&view=rev Log: Add SetDebugLocation() variant to add debug info location to an instruction. Modified: llvm/trunk/include/llvm/Support/IRBuilder.h Modified: llvm/trunk/include/llvm/Support/IRBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IRBuilder.h?rev=86859&r1=86858&r2=86859&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/IRBuilder.h (original) +++ llvm/trunk/include/llvm/Support/IRBuilder.h Wed Nov 11 13:06:06 2009 @@ -151,6 +151,15 @@ Context.getMetadata().addMD(MDKind, CurDbgLocation, I); } + /// SetDebugLocation - Set location information for the given instruction. + void SetDebugLocation(Instruction *I, MDNode *Loc) { + if (MDKind == 0) + MDKind = Context.getMetadata().getMDKind("dbg"); + if (MDKind == 0) + MDKind = Context.getMetadata().registerMDKind("dbg"); + Context.getMetadata().addMD(MDKind, Loc, I); + } + /// Insert - Insert and return the specified instruction. template InstTy *Insert(InstTy *I, const Twine &Name = "") const { From dpatel at apple.com Wed Nov 11 13:07:28 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 11 Nov 2009 19:07:28 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r86860 - /llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Message-ID: <200911111907.nABJ7SDl000985@zion.cs.uiuc.edu> Author: dpatel Date: Wed Nov 11 13:07:28 2009 New Revision: 86860 URL: http://llvm.org/viewvc/llvm-project?rev=86860&view=rev Log: Create new location to attach with llvm.dbg.declare. This location is only used to find the context of the variable by the code generator. Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=86860&r1=86859&r2=86860&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Wed Nov 11 13:07:28 2009 @@ -333,7 +333,15 @@ // Insert an llvm.dbg.declare into the current block. Instruction *Call = DebugFactory.InsertDeclare(AI, D, Builder.GetInsertBlock()); - Builder.SetDebugLocation(Call); + +#ifdef ATTACH_DEBUG_INFO_TO_AN_INSN + llvm::DIDescriptor DR = RegionStack.back(); + llvm::DIScope DS = llvm::DIScope(DR.getNode()); + llvm::DILocation DO(NULL); + llvm::DILocation DL = + DebugFactory.CreateLocation(CurLineNo, 0 /* column */, DS, DO); + Builder.SetDebugLocation(Call, DL.getNode()); +#endif } From dpatel at apple.com Wed Nov 11 13:08:42 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 11 Nov 2009 19:08:42 -0000 Subject: [llvm-commits] [llvm] r86861 - /llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp Message-ID: <200911111908.nABJ8g8s001037@zion.cs.uiuc.edu> Author: dpatel Date: Wed Nov 11 13:08:42 2009 New Revision: 86861 URL: http://llvm.org/viewvc/llvm-project?rev=86861&view=rev Log: Reenable StackTracke.cpp test. Modified: llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp Modified: llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC%2B%2B/2006-11-06-StackTrace.cpp?rev=86861&r1=86860&r2=86861&view=diff ============================================================================== --- llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp (original) +++ llvm/trunk/test/FrontendC++/2006-11-06-StackTrace.cpp Wed Nov 11 13:08:42 2009 @@ -12,7 +12,7 @@ // Only works on ppc (but not apple-darwin9), x86 and x86_64. Should // generalize? -// XFAIL: * +// XFAIL: alpha,arm,powerpc-apple-darwin9 #include From stoklund at 2pi.dk Wed Nov 11 13:31:31 2009 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 11 Nov 2009 19:31:31 -0000 Subject: [llvm-commits] [llvm] r86867 - in /llvm/trunk: include/llvm/CodeGen/LiveVariables.h lib/CodeGen/LiveVariables.cpp lib/CodeGen/PHIElimination.cpp lib/CodeGen/PHIElimination.h Message-ID: <200911111931.nABJVVao001949@zion.cs.uiuc.edu> Author: stoklund Date: Wed Nov 11 13:31:31 2009 New Revision: 86867 URL: http://llvm.org/viewvc/llvm-project?rev=86867&view=rev Log: Fix liveness calculation when splitting critical edges during PHI elimination. - Edges are split before any phis are eliminated, so the code is SSA. - Create a proper IR BasicBlock for the split edges. - LiveVariables::addNewBlock now has same syntax as MachineDominatorTree::addNewBlock. Algorithm calculates predecessor live-out set rather than successor live-in set. This feature still causes some miscompilations. Modified: llvm/trunk/include/llvm/CodeGen/LiveVariables.h llvm/trunk/lib/CodeGen/LiveVariables.cpp llvm/trunk/lib/CodeGen/PHIElimination.cpp llvm/trunk/lib/CodeGen/PHIElimination.h Modified: llvm/trunk/include/llvm/CodeGen/LiveVariables.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveVariables.h?rev=86867&r1=86866&r2=86867&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveVariables.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveVariables.h Wed Nov 11 13:31:31 2009 @@ -267,9 +267,11 @@ void HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB, MachineInstr *MI); - /// addNewBlock - Add a new basic block A as an empty predecessor of B. All - /// variables that are live into B will be marked as passing live through A. - void addNewBlock(MachineBasicBlock *A, MachineBasicBlock *B); + /// addNewBlock - Add a new basic block BB as an empty succcessor to + /// DomBB. All variables that are live out of DomBB will be marked as passing + /// live through BB. This method assumes that the machine code is still in SSA + /// form. + void addNewBlock(MachineBasicBlock *BB, MachineBasicBlock *DomBB); }; } // End llvm namespace Modified: llvm/trunk/lib/CodeGen/LiveVariables.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveVariables.cpp?rev=86867&r1=86866&r2=86867&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveVariables.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveVariables.cpp Wed Nov 11 13:31:31 2009 @@ -650,34 +650,35 @@ .push_back(BBI->getOperand(i).getReg()); } -void LiveVariables::addNewBlock(MachineBasicBlock *A, MachineBasicBlock *B) { - unsigned NumA = A->getNumber(); - unsigned NumB = B->getNumber(); +/// addNewBlock - Add a new basic block BB as an empty succcessor to DomBB. All +/// variables that are live out of DomBB will be marked as passing live through +/// BB. +void LiveVariables::addNewBlock(MachineBasicBlock *BB, + MachineBasicBlock *DomBB) { + const unsigned NumNew = BB->getNumber(); + const unsigned NumDom = DomBB->getNumber(); // Update info for all live variables - for (unsigned i = 0, e = VirtRegInfo.size(); i != e; ++i) { - VarInfo &VI = VirtRegInfo[i]; - - // Anything live through B is also live through A. - if (VI.AliveBlocks.test(NumB)) { - VI.AliveBlocks.set(NumA); + for (unsigned Reg = TargetRegisterInfo::FirstVirtualRegister, + E = MRI->getLastVirtReg()+1; Reg != E; ++Reg) { + VarInfo &VI = getVarInfo(Reg); + + // Anything live through DomBB is also live through BB. + if (VI.AliveBlocks.test(NumDom)) { + VI.AliveBlocks.set(NumNew); continue; } - // If we're not killed in B, we are not live in - if (!VI.findKill(B)) + // Variables not defined in DomBB cannot be live out. + const MachineInstr *Def = MRI->getVRegDef(Reg); + if (!Def || Def->getParent() != DomBB) continue; - unsigned Reg = i+TargetRegisterInfo::FirstVirtualRegister; + // Killed by DomBB? + if (VI.findKill(DomBB)) + continue; - // Find a def outside B - for (MachineRegisterInfo::def_iterator di = MRI->def_begin(Reg), - de=MRI->def_end(); di != de; ++di) { - if (di->getParent() != B) { - // Reg was defined outside B and killed in B - it must be live in. - VI.AliveBlocks.set(NumA); - break; - } - } + // This register is defined in DomBB and live out + VI.AliveBlocks.set(NumNew); } } Modified: llvm/trunk/lib/CodeGen/PHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIElimination.cpp?rev=86867&r1=86866&r2=86867&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/PHIElimination.cpp Wed Nov 11 13:31:31 2009 @@ -23,6 +23,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Function.h" #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/STLExtras.h" @@ -65,10 +66,17 @@ PHIDefs.clear(); PHIKills.clear(); - analyzePHINodes(Fn); bool Changed = false; + // Split critical edges to help the coalescer + if (SplitEdges) + for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) + Changed |= SplitPHIEdges(Fn, *I); + + // Populate VRegPHIUseCount + analyzePHINodes(Fn); + // Eliminate PHI instructions by inserting copies into predecessor blocks. for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) Changed |= EliminatePHINodes(Fn, *I); @@ -87,7 +95,6 @@ return Changed; } - /// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in /// predecessor basic blocks. /// @@ -96,9 +103,6 @@ if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI) return false; // Quick exit for basic blocks without PHIs. - if (SplitEdges) - SplitPHIEdges(MF, MBB); - // Get an iterator to the first instruction after the last PHI node (this may // also be the end of the basic block). MachineBasicBlock::iterator AfterPHIsIt = SkipPHIsAndLabels(MBB, MBB.begin()); @@ -293,7 +297,7 @@ // Okay, if we now know that the value is not live out of the block, we can // add a kill marker in this block saying that it kills the incoming value! // When SplitEdges is enabled, the value is never live out. - if (!ValueIsUsed && (SplitEdges || !isLiveOut(SrcReg, opBlock, *LV))) { + if (!ValueIsUsed && !isLiveOut(SrcReg, opBlock, *LV)) { // In our final twist, we have to decide which instruction kills the // register. In most cases this is the copy, however, the first // terminator instruction at the end of the block may also use the value. @@ -345,8 +349,10 @@ BBI->getOperand(i).getReg())]; } -void llvm::PHIElimination::SplitPHIEdges(MachineFunction &MF, +bool llvm::PHIElimination::SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB) { + if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI) + return false; // Quick exit for basic blocks without PHIs. LiveVariables &LV = getAnalysis(); for (MachineBasicBlock::const_iterator BBI = MBB.begin(), BBE = MBB.end(); BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI) { @@ -354,29 +360,29 @@ unsigned Reg = BBI->getOperand(i).getReg(); MachineBasicBlock *PreMBB = BBI->getOperand(i+1).getMBB(); // We break edges when registers are live out from the predecessor block - // (not considering PHI nodes). - if (isLiveOut(Reg, *PreMBB, LV)) + // (not considering PHI nodes). If the register is live in to this block + // anyway, we would gain nothing from splitting. + if (isLiveOut(Reg, *PreMBB, LV) && !isLiveIn(Reg, MBB, LV)) SplitCriticalEdge(PreMBB, &MBB); } } + return true; } bool llvm::PHIElimination::isLiveOut(unsigned Reg, const MachineBasicBlock &MBB, LiveVariables &LV) { - LiveVariables::VarInfo &InRegVI = LV.getVarInfo(Reg); + LiveVariables::VarInfo &VI = LV.getVarInfo(Reg); // Loop over all of the successors of the basic block, checking to see if // the value is either live in the block, or if it is killed in the block. std::vector OpSuccBlocks; - - // Otherwise, scan successors, including the BB the PHI node lives in. for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(), E = MBB.succ_end(); SI != E; ++SI) { MachineBasicBlock *SuccMBB = *SI; // Is it alive in this successor? unsigned SuccIdx = SuccMBB->getNumber(); - if (InRegVI.AliveBlocks.test(SuccIdx)) + if (VI.AliveBlocks.test(SuccIdx)) return true; OpSuccBlocks.push_back(SuccMBB); } @@ -386,36 +392,56 @@ switch (OpSuccBlocks.size()) { case 1: { MachineBasicBlock *SuccMBB = OpSuccBlocks[0]; - for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) - if (InRegVI.Kills[i]->getParent() == SuccMBB) + for (unsigned i = 0, e = VI.Kills.size(); i != e; ++i) + if (VI.Kills[i]->getParent() == SuccMBB) return true; break; } case 2: { MachineBasicBlock *SuccMBB1 = OpSuccBlocks[0], *SuccMBB2 = OpSuccBlocks[1]; - for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) - if (InRegVI.Kills[i]->getParent() == SuccMBB1 || - InRegVI.Kills[i]->getParent() == SuccMBB2) + for (unsigned i = 0, e = VI.Kills.size(); i != e; ++i) + if (VI.Kills[i]->getParent() == SuccMBB1 || + VI.Kills[i]->getParent() == SuccMBB2) return true; break; } default: std::sort(OpSuccBlocks.begin(), OpSuccBlocks.end()); - for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) + for (unsigned i = 0, e = VI.Kills.size(); i != e; ++i) if (std::binary_search(OpSuccBlocks.begin(), OpSuccBlocks.end(), - InRegVI.Kills[i]->getParent())) + VI.Kills[i]->getParent())) return true; } return false; } +bool llvm::PHIElimination::isLiveIn(unsigned Reg, const MachineBasicBlock &MBB, + LiveVariables &LV) { + LiveVariables::VarInfo &VI = LV.getVarInfo(Reg); + + return VI.AliveBlocks.test(MBB.getNumber()) || VI.findKill(&MBB); +} + MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A, MachineBasicBlock *B) { assert(A && B && "Missing MBB end point"); ++NumSplits; + BasicBlock *ABB = const_cast(A->getBasicBlock()); + BasicBlock *BBB = const_cast(B->getBasicBlock()); + assert(ABB && BBB && "End points must have a basic block"); + BasicBlock *BB = BasicBlock::Create(BBB->getContext(), + ABB->getName() + "." + BBB->getName() + + "_phi_edge"); + Function *F = ABB->getParent(); + F->getBasicBlockList().insert(F->end(), BB); + + BranchInst::Create(BBB, BB); + // We could do more here to produce correct IR, compare + // llvm::SplitCriticalEdge + MachineFunction *MF = A->getParent(); - MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock(B->getBasicBlock()); + MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock(BB); MF->push_back(NMBB); const unsigned NewNum = NMBB->getNumber(); DEBUG(errs() << "PHIElimination splitting critical edge:" @@ -430,21 +456,14 @@ SmallVector Cond; MF->getTarget().getInstrInfo()->InsertBranch(*NMBB, B, NULL, Cond); - LiveVariables *LV = getAnalysisIfAvailable(); - if (LV) - LV->addNewBlock(NMBB, B); + if (LiveVariables *LV = getAnalysisIfAvailable()) + LV->addNewBlock(NMBB, A); // Fix PHI nodes in B so they refer to NMBB instead of A for (MachineBasicBlock::iterator i = B->begin(), e = B->end(); i != e && i->getOpcode() == TargetInstrInfo::PHI; ++i) for (unsigned ni = 1, ne = i->getNumOperands(); ni != ne; ni += 2) - if (i->getOperand(ni+1).getMBB() == A) { + if (i->getOperand(ni+1).getMBB() == A) i->getOperand(ni+1).setMBB(NMBB); - // Mark PHI sources as passing live through NMBB - if (LV) - LV->getVarInfo(i->getOperand(ni).getReg()).AliveBlocks.set(NewNum); - } return NMBB; } - - Modified: llvm/trunk/lib/CodeGen/PHIElimination.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIElimination.h?rev=86867&r1=86866&r2=86867&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PHIElimination.h (original) +++ llvm/trunk/lib/CodeGen/PHIElimination.h Wed Nov 11 13:31:31 2009 @@ -90,7 +90,7 @@ void analyzePHINodes(const MachineFunction& Fn); /// Split critical edges where necessary for good coalescer performance. - void SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB); + bool SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB); /// isLiveOut - Determine if Reg is live out from MBB, when not /// considering PHI nodes. This means that Reg is either killed by @@ -98,6 +98,12 @@ bool isLiveOut(unsigned Reg, const MachineBasicBlock &MBB, LiveVariables &LV); + /// isLiveIn - Determine if Reg is live in to MBB, not considering PHI + /// source registers. This means that Reg is either killed by MBB or passes + /// through it. + bool isLiveIn(unsigned Reg, const MachineBasicBlock &MBB, + LiveVariables &LV); + /// SplitCriticalEdge - Split a critical edge from A to B by /// inserting a new MBB. Update branches in A and PHI instructions /// in B. Return the new block. From gohman at apple.com Wed Nov 11 13:49:00 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 11 Nov 2009 19:49:00 -0000 Subject: [llvm-commits] [llvm] r86871 - in /llvm/trunk: lib/CodeGen/BranchFolding.cpp lib/CodeGen/MachineBasicBlock.cpp test/CodeGen/Thumb2/thumb2-cbnz.ll test/CodeGen/Thumb2/thumb2-ifcvt3.ll test/CodeGen/X86/loop-blocks.ll test/CodeGen/X86/tail-opts.ll Message-ID: <200911111949.nABJn0tU002696@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 11 13:48:59 2009 New Revision: 86871 URL: http://llvm.org/viewvc/llvm-project?rev=86871&view=rev Log: Add support for tail duplication to BranchFolding, and extend tail merging support to handle more cases. - Recognize several cases where tail merging is beneficial even when the tail size is smaller than the generic threshold. - Make use of MachineInstrDesc::isBarrier to help detect non-fallthrough blocks. - Check for and avoid disrupting fall-through edges in more cases. Added: llvm/trunk/test/CodeGen/X86/tail-opts.ll Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp llvm/trunk/test/CodeGen/Thumb2/thumb2-cbnz.ll llvm/trunk/test/CodeGen/Thumb2/thumb2-ifcvt3.ll llvm/trunk/test/CodeGen/X86/loop-blocks.ll Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=86871&r1=86870&r2=86871&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Wed Nov 11 13:48:59 2009 @@ -32,6 +32,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" #include @@ -48,10 +49,16 @@ cl::desc("Max number of predecessors to consider tail merging"), cl::init(150), cl::Hidden); +// Heuristic for tail merging (and, inversely, tail duplication). +// TODO: This should be replaced with a target query. +static cl::opt +TailMergeSize("tail-merge-size", + cl::desc("Min number of instructions to consider tail merging"), + cl::init(3), cl::Hidden); char BranchFolderPass::ID = 0; -FunctionPass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge) { +Pass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge) { return new BranchFolderPass(DefaultEnableTailMerge); } @@ -442,6 +449,25 @@ } } +/// CountTerminators - Count the number of terminators in the given +/// block and set I to the position of the first non-terminator, if there +/// is one, or MBB->end() otherwise. +static unsigned CountTerminators(MachineBasicBlock *MBB, + MachineBasicBlock::iterator &I) { + I = MBB->end(); + unsigned NumTerms = 0; + for (;;) { + if (I == MBB->begin()) { + I = MBB->end(); + break; + } + --I; + if (!I->getDesc().isTerminator()) break; + ++NumTerms; + } + return NumTerms; +} + /// ProfitableToMerge - Check if two machine basic blocks have a common tail /// and decide if it would be profitable to merge those tails. Return the /// length of the common tail and iterators to the first common instruction @@ -451,16 +477,35 @@ unsigned minCommonTailLength, unsigned &CommonTailLen, MachineBasicBlock::iterator &I1, - MachineBasicBlock::iterator &I2) { + MachineBasicBlock::iterator &I2, + MachineBasicBlock *SuccBB, + MachineBasicBlock *PredBB) { CommonTailLen = ComputeCommonTailLength(MBB1, MBB2, I1, I2); MachineFunction *MF = MBB1->getParent(); - if (CommonTailLen >= minCommonTailLength) - return true; - if (CommonTailLen == 0) return false; + // It's almost always profitable to merge any number of non-terminator + // instructions with the block that falls through into the common successor. + if (MBB1 == PredBB || MBB2 == PredBB) { + MachineBasicBlock::iterator I; + unsigned NumTerms = CountTerminators(MBB1 == PredBB ? MBB2 : MBB1, I); + if (CommonTailLen > NumTerms) + return true; + } + + // If both blocks have an unconditional branch temporarily stripped out, + // treat that as an additional common instruction. + if (MBB1 != PredBB && MBB2 != PredBB && + !MBB1->back().getDesc().isBarrier() && + !MBB2->back().getDesc().isBarrier()) + --minCommonTailLength; + + // Check if the common tail is long enough to be worthwhile. + if (CommonTailLen >= minCommonTailLength) + return true; + // If we are optimizing for code size, 1 instruction in common is enough if // we don't have to split a block. At worst we will be replacing a // fallthrough into the common tail with a branch, which at worst breaks @@ -483,7 +528,9 @@ /// those blocks appear in MergePotentials (where they are not necessarily /// consecutive). unsigned BranchFolder::ComputeSameTails(unsigned CurHash, - unsigned minCommonTailLength) { + unsigned minCommonTailLength, + MachineBasicBlock *SuccBB, + MachineBasicBlock *PredBB) { unsigned maxCommonTailLength = 0U; SameTails.clear(); MachineBasicBlock::iterator TrialBBI1, TrialBBI2; @@ -495,7 +542,8 @@ for (MPIterator I = prior(CurMPIter); I->first == CurHash ; --I) { unsigned CommonTailLen; if (ProfitableToMerge(CurMPIter->second, I->second, minCommonTailLength, - CommonTailLen, TrialBBI1, TrialBBI2)) { + CommonTailLen, TrialBBI1, TrialBBI2, + SuccBB, PredBB)) { if (CommonTailLen > maxCommonTailLength) { SameTails.clear(); maxCommonTailLength = CommonTailLen; @@ -581,16 +629,62 @@ // The lone predecessor of Succ that falls through into Succ, // if any, is given in PredBB. -bool BranchFolder::TryMergeBlocks(MachineBasicBlock *SuccBB, - MachineBasicBlock* PredBB) { +bool BranchFolder::TryTailMergeBlocks(MachineBasicBlock *SuccBB, + MachineBasicBlock* PredBB) { bool MadeChange = false; - // It doesn't make sense to save a single instruction since tail merging - // will add a jump. - // FIXME: Ask the target to provide the threshold? - unsigned minCommonTailLength = (SuccBB ? 1 : 2) + 1; + // Except for the special cases below, tail-merge if there are at least + // this many instructions in common. + unsigned minCommonTailLength = TailMergeSize; + + // If there's a successor block, there are some cases which don't require + // new branching and as such are very likely to be profitable. + if (SuccBB) { + if (SuccBB->pred_size() == MergePotentials.size() && + !MergePotentials[0].second->empty()) { + // If all the predecessors have at least one tail instruction in common, + // merging is very likely to be a win since it won't require an increase + // in static branches, and it will decrease the static instruction count. + bool AllPredsMatch = true; + MachineBasicBlock::iterator FirstNonTerm; + unsigned MinNumTerms = CountTerminators(MergePotentials[0].second, + FirstNonTerm); + if (FirstNonTerm != MergePotentials[0].second->end()) { + for (unsigned i = 1, e = MergePotentials.size(); i != e; ++i) { + MachineBasicBlock::iterator OtherFirstNonTerm; + unsigned NumTerms = CountTerminators(MergePotentials[0].second, + OtherFirstNonTerm); + if (NumTerms < MinNumTerms) + MinNumTerms = NumTerms; + if (OtherFirstNonTerm == MergePotentials[i].second->end() || + OtherFirstNonTerm->isIdenticalTo(FirstNonTerm)) { + AllPredsMatch = false; + break; + } + } + + // If they all have an instruction in common, do any amount of merging. + if (AllPredsMatch) + minCommonTailLength = MinNumTerms + 1; + } + } + } - DEBUG(errs() << "\nTryMergeBlocks " << MergePotentials.size() << '\n'); + DEBUG(errs() << "\nTryTailMergeBlocks: "; + for (unsigned i = 0, e = MergePotentials.size(); i != e; ++i) + errs() << "BB#" << MergePotentials[i].second->getNumber() + << (i == e-1 ? "" : ", "); + errs() << "\n"; + if (SuccBB) { + errs() << " with successor BB#" << SuccBB->getNumber() << '\n'; + if (PredBB) + errs() << " which has fall-through from BB#" + << PredBB->getNumber() << "\n"; + } + errs() << "Looking for common tails of at least " + << minCommonTailLength << " instruction" + << (minCommonTailLength == 1 ? "" : "s") << '\n'; + ); // Sort by hash value so that blocks with identical end sequences sort // together. @@ -603,7 +697,8 @@ // Build SameTails, identifying the set of blocks with this hash code // and with the maximum number of instructions in common. unsigned maxCommonTailLength = ComputeSameTails(CurHash, - minCommonTailLength); + minCommonTailLength, + SuccBB, PredBB); // If we didn't find any pair that has at least minCommonTailLength // instructions in common, remove all blocks with this hash code and retry. @@ -621,27 +716,35 @@ unsigned int commonTailIndex, i; for (commonTailIndex=SameTails.size(), i=0; isecond; - if (MBB->begin() == SameTails[i].second && MBB != EntryBB) { + if (MBB == EntryBB) + continue; + if (MBB == PredBB) { commonTailIndex = i; - if (MBB == PredBB) - break; + break; } + if (MBB->begin() == SameTails[i].second) + commonTailIndex = i; } - if (commonTailIndex == SameTails.size()) { + if (commonTailIndex == SameTails.size() || + (SameTails[commonTailIndex].first->second == PredBB && + SameTails[commonTailIndex].first->second->begin() != + SameTails[i].second)) { // None of the blocks consist entirely of the common tail. // Split a block so that one does. - commonTailIndex = CreateCommonTailOnlyBlock(PredBB, maxCommonTailLength); + commonTailIndex = CreateCommonTailOnlyBlock(PredBB, maxCommonTailLength); } MachineBasicBlock *MBB = SameTails[commonTailIndex].first->second; // MBB is common tail. Adjust all other BB's to jump to this one. // Traversal must be forwards so erases work. - DEBUG(errs() << "\nUsing common tail BB#" << MBB->getNumber() << " for "); - for (unsigned int i=0; igetNumber() + << " for "); + for (unsigned int i=0, e = SameTails.size(); i != e; ++i) { if (commonTailIndex == i) continue; - DEBUG(errs() << "BB#" << SameTails[i].first->second->getNumber() << ", "); + DEBUG(errs() << "BB#" << SameTails[i].first->second->getNumber() + << (i == e-1 ? "" : ", ")); // Hack the end off BB i, making it jump to BB commonTailIndex instead. ReplaceTailWithBranchTo(SameTails[i].second, MBB); // BB i is no longer a predecessor of SuccBB; remove it from the worklist. @@ -671,7 +774,7 @@ // See if we can do any tail merging on those. if (MergePotentials.size() < TailMergeThreshold && MergePotentials.size() >= 2) - MadeChange |= TryMergeBlocks(NULL, NULL); + MadeChange |= TryTailMergeBlocks(NULL, NULL); // Look at blocks (IBB) with multiple predecessors (PBB). // We change each predecessor to a canonical form, by @@ -692,7 +795,8 @@ // a compile-time infinite loop repeatedly doing and undoing the same // transformations.) - for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { + for (MachineFunction::iterator I = next(MF.begin()), E = MF.end(); + I != E; ++I) { if (I->pred_size() >= 2 && I->pred_size() < TailMergeThreshold) { SmallPtrSet UniquePreds; MachineBasicBlock *IBB = I; @@ -754,13 +858,13 @@ } } if (MergePotentials.size() >= 2) - MadeChange |= TryMergeBlocks(I, PredBB); + MadeChange |= TryTailMergeBlocks(IBB, PredBB); // Reinsert an unconditional branch if needed. - // The 1 below can occur as a result of removing blocks in TryMergeBlocks. - PredBB = prior(I); // this may have been changed in TryMergeBlocks + // The 1 below can occur as a result of removing blocks in TryTailMergeBlocks. + PredBB = prior(I); // this may have been changed in TryTailMergeBlocks if (MergePotentials.size() == 1 && MergePotentials.begin()->second != PredBB) - FixTail(MergePotentials.begin()->second, I, TII); + FixTail(MergePotentials.begin()->second, IBB, TII); } } return MadeChange; @@ -813,9 +917,17 @@ if (!CurBB->isSuccessor(Fallthrough)) return false; - // If we couldn't analyze the branch, assume it could fall through. - if (BranchUnAnalyzable) return true; - + // If we couldn't analyze the branch, examine the last instruction. + // If the block doesn't end in a known control barrier, assume fallthrough + // is possible. The isPredicable check is needed because this code can be + // called during IfConversion, where an instruction which is normally a + // Barrier is predicated and thus no longer an actual control barrier. This + // is over-conservative though, because if an instruction isn't actually + // predicated we could still treat it like a barrier. + if (BranchUnAnalyzable) + return CurBB->empty() || !CurBB->back().getDesc().isBarrier() || + CurBB->back().getDesc().isPredicable(); + // If there is no branch, control always falls through. if (TBB == 0) return true; @@ -870,11 +982,108 @@ return MBB2I->getDesc().isCall() && !MBB1I->getDesc().isCall(); } +/// TailDuplicate - MBB unconditionally branches to SuccBB. If it is profitable, +/// duplicate SuccBB's contents in MBB to eliminate the branch. +bool BranchFolder::TailDuplicate(MachineBasicBlock *TailBB, + bool PrevFallsThrough, + MachineFunction &MF) { + // Don't try to tail-duplicate single-block loops. + if (TailBB->isSuccessor(TailBB)) + return false; + + // Don't tail-duplicate a block which will soon be folded into its successor. + if (TailBB->succ_size() == 1 && + TailBB->succ_begin()[0]->pred_size() == 1) + return false; + + // Duplicate up to one less that the tail-merge threshold, so that we don't + // get into an infinite loop between duplicating and merging. When optimizing + // for size, duplicate only one, because one branch instruction can be + // eliminated to compensate for the duplication. + unsigned MaxDuplicateCount = + MF.getFunction()->hasFnAttr(Attribute::OptimizeForSize) ? + 1 : (TailMergeSize - 1); + + // Check the instructions in the block to determine whether tail-duplication + // is invalid or unlikely to be unprofitable. + unsigned i = 0; + bool HasCall = false; + for (MachineBasicBlock::iterator I = TailBB->begin(); + I != TailBB->end(); ++I, ++i) { + // Non-duplicable things shouldn't be tail-duplicated. + if (I->getDesc().isNotDuplicable()) return false; + // Don't duplicate more than the threshold. + if (i == MaxDuplicateCount) return false; + // Remember if we saw a call. + if (I->getDesc().isCall()) HasCall = true; + } + // Heuristically, don't tail-duplicate calls if it would expand code size, + // as it's less likely to be worth the extra cost. + if (i > 1 && HasCall) + return false; + + // Iterate through all the unique predecessors and tail-duplicate this + // block into them, if possible. Copying the list ahead of time also + // avoids trouble with the predecessor list reallocating. + bool Changed = false; + SmallSetVector Preds(TailBB->pred_begin(), + TailBB->pred_end()); + for (SmallSetVector::iterator PI = Preds.begin(), + PE = Preds.end(); PI != PE; ++PI) { + MachineBasicBlock *PredBB = *PI; + + assert(TailBB != PredBB && + "Single-block loop should have been rejected earlier!"); + if (PredBB->succ_size() > 1) continue; + + MachineBasicBlock *PredTBB, *PredFBB; + SmallVector PredCond; + if (TII->AnalyzeBranch(*PredBB, PredTBB, PredFBB, PredCond, true)) + continue; + if (!PredCond.empty()) + continue; + // EH edges are ignored by AnalyzeBranch. + if (PredBB->succ_size() != 1) + continue; + // Don't duplicate into a fall-through predecessor unless its the + // only predecessor. + if (&*next(MachineFunction::iterator(PredBB)) == TailBB && + PrevFallsThrough && + TailBB->pred_size() != 1) + continue; + + DEBUG(errs() << "\nTail-duplicating into PredBB: " << *PredBB + << "From Succ: " << *TailBB); + + // Remove PredBB's unconditional branch. + TII->RemoveBranch(*PredBB); + // Clone the contents of TailBB into PredBB. + for (MachineBasicBlock::iterator I = TailBB->begin(), E = TailBB->end(); + I != E; ++I) { + MachineInstr *NewMI = MF.CloneMachineInstr(I); + PredBB->insert(PredBB->end(), NewMI); + } + + // Update the CFG. + PredBB->removeSuccessor(PredBB->succ_begin()); + assert(PredBB->succ_empty() && + "TailDuplicate called on block with multiple successors!"); + for (MachineBasicBlock::succ_iterator I = TailBB->succ_begin(), + E = TailBB->succ_end(); I != E; ++I) + PredBB->addSuccessor(*I); + + Changed = true; + } + + return Changed; +} + /// OptimizeBlock - Analyze and optimize control flow related to the specified /// block. This is never called on the entry block. bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { bool MadeChange = false; MachineFunction &MF = *MBB->getParent(); +ReoptimizeBlock: MachineFunction::iterator FallThrough = MBB; ++FallThrough; @@ -927,16 +1136,36 @@ TII->InsertBranch(PrevBB, PriorTBB, 0, PriorCond); MadeChange = true; ++NumBranchOpts; - return OptimizeBlock(MBB); + goto ReoptimizeBlock; } + // If the previous block unconditionally falls through to this block and + // this block has no other predecessors, move the contents of this block + // into the prior block. This doesn't usually happen when SimplifyCFG + // has been used, but it can happen tail duplication eliminates all the + // non-branch predecessors of a block leaving only the fall-through edge. + // This has to check PrevBB->succ_size() because EH edges are ignored by + // AnalyzeBranch. + if (PriorCond.empty() && !PriorTBB && MBB->pred_size() == 1 && + PrevBB.succ_size() == 1 && + !MBB->hasAddressTaken()) { + DEBUG(errs() << "\nMerging into block: " << PrevBB + << "From MBB: " << *MBB); + PrevBB.splice(PrevBB.end(), MBB, MBB->begin(), MBB->end()); + PrevBB.removeSuccessor(PrevBB.succ_begin());; + assert(PrevBB.succ_empty()); + PrevBB.transferSuccessors(MBB); + MadeChange = true; + return MadeChange; + } + // If the previous branch *only* branches to *this* block (conditional or // not) remove the branch. if (PriorTBB == MBB && PriorFBB == 0) { TII->RemoveBranch(PrevBB); MadeChange = true; ++NumBranchOpts; - return OptimizeBlock(MBB); + goto ReoptimizeBlock; } // If the prior block branches somewhere else on the condition and here if @@ -946,7 +1175,7 @@ TII->InsertBranch(PrevBB, PriorTBB, 0, PriorCond); MadeChange = true; ++NumBranchOpts; - return OptimizeBlock(MBB); + goto ReoptimizeBlock; } // If the prior block branches here on true and somewhere else on false, and @@ -959,7 +1188,7 @@ TII->InsertBranch(PrevBB, PriorFBB, 0, NewPriorCond); MadeChange = true; ++NumBranchOpts; - return OptimizeBlock(MBB); + goto ReoptimizeBlock; } } @@ -1041,7 +1270,7 @@ TII->InsertBranch(*MBB, CurFBB, CurTBB, NewCond); MadeChange = true; ++NumBranchOpts; - return OptimizeBlock(MBB); + goto ReoptimizeBlock; } } @@ -1107,7 +1336,7 @@ TII->InsertBranch(*PMBB, NewCurTBB, 0, NewCurCond); MadeChange = true; ++NumBranchOpts; - PMBB->CorrectExtraCFGEdges(NewCurTBB, NewCurFBB, false); + PMBB->CorrectExtraCFGEdges(NewCurTBB, 0, false); } } } @@ -1127,16 +1356,26 @@ } } + // Now we know that there was no fall-through into this block, check to + // see if it has a fall-through into its successor. + bool CurFallsThru = CanFallThrough(MBB, CurUnAnalyzable, CurTBB, CurFBB, + CurCond); + bool PrevFallsThru = CanFallThrough(&PrevBB, PriorUnAnalyzable, + PriorTBB, PriorFBB, PriorCond); + + // If this block is small, unconditionally branched to, and does not + // fall through, tail-duplicate its instructions into its predecessors + // to eliminate a (dynamic) branch. + if (!CurFallsThru) + if (TailDuplicate(MBB, PrevFallsThru, MF)) { + MadeChange = true; + return MadeChange; + } + // If the prior block doesn't fall through into this block, and if this // block doesn't fall through into some other block, see if we can find a // place to move this block where a fall-through will happen. - if (!CanFallThrough(&PrevBB, PriorUnAnalyzable, - PriorTBB, PriorFBB, PriorCond)) { - // Now we know that there was no fall-through into this block, check to - // see if it has a fall-through into its successor. - bool CurFallsThru = CanFallThrough(MBB, CurUnAnalyzable, CurTBB, CurFBB, - CurCond); - + if (!PrevFallsThru) { if (!MBB->isLandingPad()) { // Check all the predecessors of this block. If one of them has no fall // throughs, move this block right after it. @@ -1145,7 +1384,10 @@ // Analyze the branch at the end of the pred. MachineBasicBlock *PredBB = *PI; MachineFunction::iterator PredFallthrough = PredBB; ++PredFallthrough; - if (PredBB != MBB && !CanFallThrough(PredBB) + MachineBasicBlock *PredTBB, *PredFBB; + SmallVector PredCond; + if (PredBB != MBB && !CanFallThrough(PredBB) && + !TII->AnalyzeBranch(*PredBB, PredTBB, PredFBB, PredCond, true) && (!CurFallsThru || !CurTBB || !CurFBB) && (!CurFallsThru || MBB->getNumber() >= PredBB->getNumber())) { // If the current block doesn't fall through, just move it. @@ -1165,7 +1407,7 @@ } MBB->moveAfter(PredBB); MadeChange = true; - return OptimizeBlock(MBB); + goto ReoptimizeBlock; } } } @@ -1182,18 +1424,22 @@ // the succ doesn't already have a block that can fall through into it, // and if the successor isn't an EH destination, we can arrange for the // fallthrough to happen. - if (SuccBB != MBB && !CanFallThrough(SuccPrev) && + if (SuccBB != MBB && &*SuccPrev != MBB && + !CanFallThrough(SuccPrev) && !CurUnAnalyzable && !SuccBB->isLandingPad()) { MBB->moveBefore(SuccBB); MadeChange = true; - return OptimizeBlock(MBB); + goto ReoptimizeBlock; } } // Okay, there is no really great place to put this block. If, however, // the block before this one would be a fall-through if this block were // removed, move this block to the end of the function. + MachineBasicBlock *PrevTBB, *PrevFBB; + SmallVector PrevCond; if (FallThrough != MF.end() && + !TII->AnalyzeBranch(PrevBB, PrevTBB, PrevFBB, PrevCond, true) && PrevBB.isSuccessor(FallThrough)) { MBB->moveAfter(--MF.end()); MadeChange = true; Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=86871&r1=86870&r2=86871&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Wed Nov 11 13:48:59 2009 @@ -371,10 +371,7 @@ MachineBasicBlock::succ_iterator SI = succ_begin(); MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB; while (SI != succ_end()) { - if (*SI == DestA && DestA == DestB) { - DestA = DestB = 0; - ++SI; - } else if (*SI == DestA) { + if (*SI == DestA) { DestA = 0; ++SI; } else if (*SI == DestB) { Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-cbnz.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-cbnz.ll?rev=86871&r1=86870&r2=86871&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/thumb2-cbnz.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/thumb2-cbnz.ll Wed Nov 11 13:48:59 2009 @@ -20,7 +20,8 @@ br i1 %a, label %bb11, label %bb9 bb9: ; preds = %bb7 -; CHECK: @ BB#2: +; CHECK: cmp r0, #0 +; CHECK-NEXT: cmp r0, #0 ; CHECK-NEXT: cbnz %0 = tail call arm_apcscc double @floor(double %b) nounwind readnone ; [#uses=0] br label %bb11 Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-ifcvt3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-ifcvt3.ll?rev=86871&r1=86870&r2=86871&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/thumb2-ifcvt3.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/thumb2-ifcvt3.ll Wed Nov 11 13:48:59 2009 @@ -23,7 +23,7 @@ ; CHECK: movne ; CHECK: moveq ; CHECK: pop -; CHECK-NEXT: LBB1_2: +; CHECK-NEXT: LBB1_1: %0 = load i64* @posed, align 4 ; [#uses=3] %1 = sub i64 %0, %.reload78 ; [#uses=1] %2 = ashr i64 %1, 1 ; [#uses=3] Modified: llvm/trunk/test/CodeGen/X86/loop-blocks.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-blocks.ll?rev=86871&r1=86870&r2=86871&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/loop-blocks.ll (original) +++ llvm/trunk/test/CodeGen/X86/loop-blocks.ll Wed Nov 11 13:48:59 2009 @@ -74,16 +74,16 @@ ; CHECK: yet_more_involved: ; CHECK: jmp .LBB3_1 ; CHECK-NEXT: align -; CHECK-NEXT: .LBB3_3: +; CHECK-NEXT: .LBB3_4: ; CHECK-NEXT: call bar99 ; CHECK-NEXT: call get ; CHECK-NEXT: cmpl $2999, %eax -; CHECK-NEXT: jg .LBB3_5 +; CHECK-NEXT: jg .LBB3_6 ; CHECK-NEXT: call block_a_true_func -; CHECK-NEXT: jmp .LBB3_6 -; CHECK-NEXT: .LBB3_5: -; CHECK-NEXT: call block_a_false_func +; CHECK-NEXT: jmp .LBB3_7 ; CHECK-NEXT: .LBB3_6: +; CHECK-NEXT: call block_a_false_func +; CHECK-NEXT: .LBB3_7: ; CHECK-NEXT: call block_a_merge_func ; CHECK-NEXT: .LBB3_1: ; CHECK-NEXT: call body Added: llvm/trunk/test/CodeGen/X86/tail-opts.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tail-opts.ll?rev=86871&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/tail-opts.ll (added) +++ llvm/trunk/test/CodeGen/X86/tail-opts.ll Wed Nov 11 13:48:59 2009 @@ -0,0 +1,268 @@ +; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -asm-verbose=false | FileCheck %s + +declare void @bar(i32) +declare void @car(i32) +declare void @dar(i32) +declare void @ear(i32) +declare void @far(i32) +declare i1 @qux() + + at GHJK = global i32 0 + at HABC = global i32 0 + +; BranchFolding should tail-merge the stores since they all precede +; direct branches to the same place. + +; CHECK: tail_merge_me: +; CHECK-NOT: GHJK +; CHECK: movl $0, GHJK(%rip) +; CHECK-NEXT: movl $1, HABC(%rip) +; CHECK-NOT: GHJK + +define void @tail_merge_me() nounwind { +entry: + %a = call i1 @qux() + br i1 %a, label %A, label %next +next: + %b = call i1 @qux() + br i1 %b, label %B, label %C + +A: + call void @bar(i32 0) + store i32 0, i32* @GHJK + br label %M + +B: + call void @car(i32 1) + store i32 0, i32* @GHJK + br label %M + +C: + call void @dar(i32 2) + store i32 0, i32* @GHJK + br label %M + +M: + store i32 1, i32* @HABC + %c = call i1 @qux() + br i1 %c, label %return, label %altret + +return: + call void @ear(i32 1000) + ret void +altret: + call void @far(i32 1001) + ret void +} + +declare i8* @choose(i8*, i8*); + +; BranchFolding should tail-duplicate the indirect jump to avoid +; redundant branching. + +; CHECK: tail_duplicate_me: +; CHECK: movl $0, GHJK(%rip) +; CHECK-NEXT: jmpq *%rbx +; CHECK: movl $0, GHJK(%rip) +; CHECK-NEXT: jmpq *%rbx +; CHECK: movl $0, GHJK(%rip) +; CHECK-NEXT: jmpq *%rbx + +define void @tail_duplicate_me() nounwind { +entry: + %a = call i1 @qux() + %c = call i8* @choose(i8* blockaddress(@tail_duplicate_me, %return), + i8* blockaddress(@tail_duplicate_me, %altret)) + br i1 %a, label %A, label %next +next: + %b = call i1 @qux() + br i1 %b, label %B, label %C + +A: + call void @bar(i32 0) + store i32 0, i32* @GHJK + br label %M + +B: + call void @car(i32 1) + store i32 0, i32* @GHJK + br label %M + +C: + call void @dar(i32 2) + store i32 0, i32* @GHJK + br label %M + +M: + indirectbr i8* %c, [label %return, label %altret] + +return: + call void @ear(i32 1000) + ret void +altret: + call void @far(i32 1001) + ret void +} + +; BranchFolding shouldn't try to merge the tails of two blocks +; with only a branch in common, regardless of the fallthrough situation. + +; CHECK: dont_merge_oddly: +; CHECK-NOT: ret +; CHECK: ucomiss %xmm0, %xmm1 +; CHECK-NEXT: jbe .LBB3_3 +; CHECK-NEXT: ucomiss %xmm2, %xmm0 +; CHECK-NEXT: ja .LBB3_4 +; CHECK-NEXT: .LBB3_2: +; CHECK-NEXT: movb $1, %al +; CHECK-NEXT: ret +; CHECK-NEXT: .LBB3_3: +; CHECK-NEXT: ucomiss %xmm2, %xmm1 +; CHECK-NEXT: jbe .LBB3_2 +; CHECK-NEXT: .LBB3_4: +; CHECK-NEXT: xorb %al, %al +; CHECK-NEXT: ret + +define i1 @dont_merge_oddly(float* %result) nounwind { +entry: + %tmp4 = getelementptr float* %result, i32 2 + %tmp5 = load float* %tmp4, align 4 + %tmp7 = getelementptr float* %result, i32 4 + %tmp8 = load float* %tmp7, align 4 + %tmp10 = getelementptr float* %result, i32 6 + %tmp11 = load float* %tmp10, align 4 + %tmp12 = fcmp olt float %tmp8, %tmp11 + br i1 %tmp12, label %bb, label %bb21 + +bb: + %tmp23469 = fcmp olt float %tmp5, %tmp8 + br i1 %tmp23469, label %bb26, label %bb30 + +bb21: + %tmp23 = fcmp olt float %tmp5, %tmp11 + br i1 %tmp23, label %bb26, label %bb30 + +bb26: + ret i1 0 + +bb30: + ret i1 1 +} + +; Do any-size tail-merging when two candidate blocks will both require +; an unconditional jump to complete a two-way conditional branch. + +; CHECK: c_expand_expr_stmt: +; CHECK: jmp .LBB4_7 +; CHECK-NEXT: .LBB4_12: +; CHECK-NEXT: movq 8(%rax), %rax +; CHECK-NEXT: movb 16(%rax), %al +; CHECK-NEXT: cmpb $16, %al +; CHECK-NEXT: je .LBB4_6 +; CHECK-NEXT: cmpb $23, %al +; CHECK-NEXT: je .LBB4_6 +; CHECK-NEXT: jmp .LBB4_15 +; CHECK-NEXT: .LBB4_14: +; CHECK-NEXT: cmpb $23, %bl +; CHECK-NEXT: jne .LBB4_15 +; CHECK-NEXT: .LBB4_15: + +%0 = type { %struct.rtx_def* } +%struct.lang_decl = type opaque +%struct.rtx_def = type { i16, i8, i8, [1 x %union.rtunion] } +%struct.tree_decl = type { [24 x i8], i8*, i32, %union.tree_node*, i32, i8, i8, i8, i8, %union.tree_node*, %union.tree_node*, %union.tree_node*, %union.tree_node*, %union.tree_node*, %union.tree_node*, %union.tree_node*, %union.tree_node*, %union.tree_node*, %struct.rtx_def*, %union..2anon, %0, %union.tree_node*, %struct.lang_decl* } +%union..2anon = type { i32 } +%union.rtunion = type { i8* } +%union.tree_node = type { %struct.tree_decl } + +define fastcc void @c_expand_expr_stmt(%union.tree_node* %expr) nounwind { +entry: + %tmp4 = load i8* null, align 8 ; [#uses=3] + switch i8 %tmp4, label %bb3 [ + i8 18, label %bb + ] + +bb: ; preds = %entry + switch i32 undef, label %bb1 [ + i32 0, label %bb2.i + i32 37, label %bb.i + ] + +bb.i: ; preds = %bb + switch i32 undef, label %bb1 [ + i32 0, label %lvalue_p.exit + ] + +bb2.i: ; preds = %bb + br label %bb3 + +lvalue_p.exit: ; preds = %bb.i + %tmp21 = load %union.tree_node** null, align 8 ; <%union.tree_node*> [#uses=3] + %tmp22 = getelementptr inbounds %union.tree_node* %tmp21, i64 0, i32 0, i32 0, i64 0 ; [#uses=1] + %tmp23 = load i8* %tmp22, align 8 ; [#uses=1] + %tmp24 = zext i8 %tmp23 to i32 ; [#uses=1] + switch i32 %tmp24, label %lvalue_p.exit4 [ + i32 0, label %bb2.i3 + i32 2, label %bb.i1 + ] + +bb.i1: ; preds = %lvalue_p.exit + %tmp25 = getelementptr inbounds %union.tree_node* %tmp21, i64 0, i32 0, i32 2 ; [#uses=1] + %tmp26 = bitcast i32* %tmp25 to %union.tree_node** ; <%union.tree_node**> [#uses=1] + %tmp27 = load %union.tree_node** %tmp26, align 8 ; <%union.tree_node*> [#uses=2] + %tmp28 = getelementptr inbounds %union.tree_node* %tmp27, i64 0, i32 0, i32 0, i64 16 ; [#uses=1] + %tmp29 = load i8* %tmp28, align 8 ; [#uses=1] + %tmp30 = zext i8 %tmp29 to i32 ; [#uses=1] + switch i32 %tmp30, label %lvalue_p.exit4 [ + i32 0, label %bb2.i.i2 + i32 2, label %bb.i.i + ] + +bb.i.i: ; preds = %bb.i1 + %tmp34 = tail call fastcc i32 @lvalue_p(%union.tree_node* null) nounwind ; [#uses=1] + %phitmp = icmp ne i32 %tmp34, 0 ; [#uses=1] + br label %lvalue_p.exit4 + +bb2.i.i2: ; preds = %bb.i1 + %tmp35 = getelementptr inbounds %union.tree_node* %tmp27, i64 0, i32 0, i32 0, i64 8 ; [#uses=1] + %tmp36 = bitcast i8* %tmp35 to %union.tree_node** ; <%union.tree_node**> [#uses=1] + %tmp37 = load %union.tree_node** %tmp36, align 8 ; <%union.tree_node*> [#uses=1] + %tmp38 = getelementptr inbounds %union.tree_node* %tmp37, i64 0, i32 0, i32 0, i64 16 ; [#uses=1] + %tmp39 = load i8* %tmp38, align 8 ; [#uses=1] + switch i8 %tmp39, label %bb2 [ + i8 16, label %lvalue_p.exit4 + i8 23, label %lvalue_p.exit4 + ] + +bb2.i3: ; preds = %lvalue_p.exit + %tmp40 = getelementptr inbounds %union.tree_node* %tmp21, i64 0, i32 0, i32 0, i64 8 ; [#uses=1] + %tmp41 = bitcast i8* %tmp40 to %union.tree_node** ; <%union.tree_node**> [#uses=1] + %tmp42 = load %union.tree_node** %tmp41, align 8 ; <%union.tree_node*> [#uses=1] + %tmp43 = getelementptr inbounds %union.tree_node* %tmp42, i64 0, i32 0, i32 0, i64 16 ; [#uses=1] + %tmp44 = load i8* %tmp43, align 8 ; [#uses=1] + switch i8 %tmp44, label %bb2 [ + i8 16, label %lvalue_p.exit4 + i8 23, label %lvalue_p.exit4 + ] + +lvalue_p.exit4: ; preds = %bb2.i3, %bb2.i3, %bb2.i.i2, %bb2.i.i2, %bb.i.i, %bb.i1, %lvalue_p.exit + %tmp45 = phi i1 [ %phitmp, %bb.i.i ], [ false, %bb2.i.i2 ], [ false, %bb2.i.i2 ], [ false, %bb.i1 ], [ false, %bb2.i3 ], [ false, %bb2.i3 ], [ false, %lvalue_p.exit ] ; [#uses=1] + %tmp46 = icmp eq i8 %tmp4, 0 ; [#uses=1] + %or.cond = or i1 %tmp45, %tmp46 ; [#uses=1] + br i1 %or.cond, label %bb2, label %bb3 + +bb1: ; preds = %bb2.i.i, %bb.i, %bb + %.old = icmp eq i8 %tmp4, 23 ; [#uses=1] + br i1 %.old, label %bb2, label %bb3 + +bb2: ; preds = %bb1, %lvalue_p.exit4, %bb2.i3, %bb2.i.i2 + br label %bb3 + +bb3: ; preds = %bb2, %bb1, %lvalue_p.exit4, %bb2.i, %entry + %expr_addr.0 = phi %union.tree_node* [ null, %bb2 ], [ %expr, %bb2.i ], [ %expr, %entry ], [ %expr, %bb1 ], [ %expr, %lvalue_p.exit4 ] ; <%union.tree_node*> [#uses=0] + unreachable +} + +declare fastcc i32 @lvalue_p(%union.tree_node* nocapture) nounwind readonly + +declare fastcc %union.tree_node* @default_conversion(%union.tree_node*) nounwind From gohman at apple.com Wed Nov 11 13:49:34 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 11 Nov 2009 19:49:34 -0000 Subject: [llvm-commits] [llvm] r86873 - /llvm/trunk/lib/CodeGen/BranchFolding.h Message-ID: <200911111949.nABJnYak002738@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 11 13:49:34 2009 New Revision: 86873 URL: http://llvm.org/viewvc/llvm-project?rev=86873&view=rev Log: Check in the changes to this file too. Modified: llvm/trunk/lib/CodeGen/BranchFolding.h Modified: llvm/trunk/lib/CodeGen/BranchFolding.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.h?rev=86873&r1=86872&r2=86873&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.h (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.h Wed Nov 11 13:49:34 2009 @@ -44,18 +44,24 @@ RegScavenger *RS; bool TailMergeBlocks(MachineFunction &MF); - bool TryMergeBlocks(MachineBasicBlock* SuccBB, - MachineBasicBlock* PredBB); + bool TryTailMergeBlocks(MachineBasicBlock* SuccBB, + MachineBasicBlock* PredBB); void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, MachineBasicBlock *NewDest); MachineBasicBlock *SplitMBBAt(MachineBasicBlock &CurMBB, MachineBasicBlock::iterator BBI1); - unsigned ComputeSameTails(unsigned CurHash, unsigned minCommonTailLength); + unsigned ComputeSameTails(unsigned CurHash, unsigned minCommonTailLength, + MachineBasicBlock *SuccBB, + MachineBasicBlock *PredBB); void RemoveBlocksWithHash(unsigned CurHash, MachineBasicBlock* SuccBB, MachineBasicBlock* PredBB); unsigned CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB, unsigned maxCommonTailLength); + bool TailDuplicate(MachineBasicBlock *TailBB, + bool PrevFallsThrough, + MachineFunction &MF); + bool OptimizeBranches(MachineFunction &MF); bool OptimizeBlock(MachineBasicBlock *MBB); void RemoveDeadBlock(MachineBasicBlock *MBB); From vkutuzov at accesssoftek.com Wed Nov 11 13:53:56 2009 From: vkutuzov at accesssoftek.com (Viktor Kutuzov) Date: Wed, 11 Nov 2009 11:53:56 -0800 Subject: [llvm-commits] [PATCH] LTO code generator options References: <04F6B1512E264B27AEE607542FCDD113@andreic6e7fe55> <9C7CA4093A8F41D7AD156ED3CF854D17@andreic6e7fe55> <38a0d8450911101625s5e3b7cb0m31ec0ce4d4144dc@mail.gmail.com> Message-ID: Thanks for the review, Rafael. I appreciate that you did it even with all those cosmetic changes there. Sorry for the white spaces in that patch. I'll keep it separate from now on. The updated patch is attached. * StringRef is passed by value; * Removed getArchNameForLLVMArchType; * Fixed strange alignment. * Removed all cosmetic changes from this patch. Is it Ok to submit? Cheers, Viktor ----- Original Message ----- From: "Rafael Espindola" To: "Viktor Kutuzov" Cc: "Commit Messages and Patches for LLVM" Sent: Tuesday, November 10, 2009 4:25 PM Subject: Re: [llvm-commits] [PATCH] LTO code generator options > 2009/11/10 Viktor Kutuzov : >> Is this Ok to submit? > > Small comments: > > * StringRef is normally passed by value. > * Can you put the header reordering and white space in an independent patch? > * Part of the alignment looks strange: > + if (!MAttrs.empty()) > + features.AddFeatures(MAttrs); > * getArchNameForLLVMArchType is not used > >> Best regards, >> Viktor > > Cheers, > -- > Rafael ?vila de Esp?ndola > -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-lto-codegen-target_override-02.diff Type: application/octet-stream Size: 22783 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091111/529ef66c/attachment.obj From dpatel at apple.com Wed Nov 11 13:55:08 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 11 Nov 2009 19:55:08 -0000 Subject: [llvm-commits] [llvm] r86874 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Message-ID: <200911111955.nABJt86w002938@zion.cs.uiuc.edu> Author: dpatel Date: Wed Nov 11 13:55:08 2009 New Revision: 86874 URL: http://llvm.org/viewvc/llvm-project?rev=86874&view=rev Log: If doesSupportDebugInformation() is false then do not try to emit dwarf debug info. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=86874&r1=86873&r2=86874&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed Nov 11 13:55:08 2009 @@ -1905,6 +1905,9 @@ if (TimePassesIsEnabled) DebugTimer->startTimer(); + if (!MAI->doesSupportDebugInformation()) + return; + DebugInfoFinder DbgFinder; DbgFinder.processModule(*M); From gohman at apple.com Wed Nov 11 13:56:06 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 11 Nov 2009 19:56:06 -0000 Subject: [llvm-commits] [llvm] r86875 - /llvm/trunk/lib/CodeGen/BranchFolding.cpp Message-ID: <200911111956.nABJu6se002982@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 11 13:56:05 2009 New Revision: 86875 URL: http://llvm.org/viewvc/llvm-project?rev=86875&view=rev Log: Revert this line of 86871. Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=86875&r1=86874&r2=86875&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Wed Nov 11 13:56:05 2009 @@ -58,7 +58,7 @@ char BranchFolderPass::ID = 0; -Pass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge) { +FunctionPass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge) { return new BranchFolderPass(DefaultEnableTailMerge); } From nicholas at mxc.ca Wed Nov 11 13:56:16 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 11 Nov 2009 11:56:16 -0800 Subject: [llvm-commits] [PATCH] LTO code generator options: --verbose In-Reply-To: <214DD1AE30F746F5B0086F4773D23D32@andreic6e7fe55> References: <6AE1604EE3EC5F4296C096518C6B77EEF99C4FAA@mail.accesssoftek.com> <7383326612F04B4DA85C26A2C9A4E6D4@andreic6e7fe55> <4C3AAB5F-812D-4811-A1EE-DEF04E0F29EE@apple.com> <214DD1AE30F746F5B0086F4773D23D32@andreic6e7fe55> Message-ID: <4AFB16E0.9040103@mxc.ca> Viktor Kutuzov wrote: > Please find attached the patch without cosmetic changes. Why do you need this? Or rather, when would a user want to specify this? If this is just debugging info, why not use DEBUG() from llvm/Support/Debug.h? Nick > Best regards, > Viktor > > ----- Original Message ----- From: "Eric Christopher" > To: "Viktor Kutuzov" > Cc: "Commit Messages and Patches for LLVM" > Sent: Tuesday, November 10, 2009 1:15 PM > Subject: Re: [llvm-commits] [PATCH] LTO code generator options: --verbose > > > > On Nov 10, 2009, at 1:10 PM, Viktor Kutuzov wrote: > >> > > It'd be easier to look at if there were less cosmetic changes in the > patch. That said, what do you expect this will add? > > -eric > > > ------------------------------------------------------------------------ > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From kennethuil at gmail.com Wed Nov 11 13:59:25 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Wed, 11 Nov 2009 19:59:25 -0000 Subject: [llvm-commits] [llvm] r86876 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.h test/CodeGen/X86/bigstructret.ll Message-ID: <200911111959.nABJxPDw003185@zion.cs.uiuc.edu> Author: kennethuil Date: Wed Nov 11 13:59:24 2009 New Revision: 86876 URL: http://llvm.org/viewvc/llvm-project?rev=86876&view=rev Log: x86 users can now return arbitrary sized structs. Structs too large to fit in return registers will be returned through a hidden sret parameter introduced during SelectionDAG construction. Added: llvm/trunk/test/CodeGen/X86/bigstructret.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=86876&r1=86875&r2=86876&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Wed Nov 11 13:59:24 2009 @@ -951,23 +951,23 @@ /// Get the EVTs and ArgFlags collections that represent the return type /// of the given function. This does not require a DAG or a return value, and /// is suitable for use before any DAGs for the function are constructed. -static void getReturnInfo(const Function* F, SmallVectorImpl &OutVTs, +static void getReturnInfo(const Type* ReturnType, + Attributes attr, SmallVectorImpl &OutVTs, SmallVectorImpl &OutFlags, - TargetLowering &TLI) { - const Type* ReturnType = F->getReturnType(); - + TargetLowering &TLI, + SmallVectorImpl *Offsets = 0) { SmallVector ValueVTs; - ComputeValueVTs(TLI, ReturnType, ValueVTs); + ComputeValueVTs(TLI, ReturnType, ValueVTs, Offsets); unsigned NumValues = ValueVTs.size(); if ( NumValues == 0 ) return; for (unsigned j = 0, f = NumValues; j != f; ++j) { EVT VT = ValueVTs[j]; ISD::NodeType ExtendKind = ISD::ANY_EXTEND; - - if (F->paramHasAttr(0, Attribute::SExt)) + + if (attr & Attribute::SExt) ExtendKind = ISD::SIGN_EXTEND; - else if (F->paramHasAttr(0, Attribute::ZExt)) + else if (attr & Attribute::ZExt) ExtendKind = ISD::ZERO_EXTEND; // FIXME: C calling convention requires the return type to be promoted to @@ -975,26 +975,25 @@ // conventions. The frontend should mark functions whose return values // require promoting with signext or zeroext attributes. if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { - EVT MinVT = TLI.getRegisterType(F->getContext(), MVT::i32); + EVT MinVT = TLI.getRegisterType(ReturnType->getContext(), MVT::i32); if (VT.bitsLT(MinVT)) VT = MinVT; } - unsigned NumParts = TLI.getNumRegisters(F->getContext(), VT); - EVT PartVT = TLI.getRegisterType(F->getContext(), VT); + unsigned NumParts = TLI.getNumRegisters(ReturnType->getContext(), VT); + EVT PartVT = TLI.getRegisterType(ReturnType->getContext(), VT); // 'inreg' on function refers to return value ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy(); - if (F->paramHasAttr(0, Attribute::InReg)) + if (attr & Attribute::InReg) Flags.setInReg(); // Propagate extension type if any - if (F->paramHasAttr(0, Attribute::SExt)) + if (attr & Attribute::SExt) Flags.setSExt(); - else if (F->paramHasAttr(0, Attribute::ZExt)) + else if (attr & Attribute::ZExt) Flags.setZExt(); - for (unsigned i = 0; i < NumParts; ++i) - { + for (unsigned i = 0; i < NumParts; ++i) { OutVTs.push_back(PartVT); OutFlags.push_back(Flags); } @@ -1004,54 +1003,88 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) { SDValue Chain = getControlRoot(); SmallVector Outs; - for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { + FunctionLoweringInfo &FLI = DAG.getFunctionLoweringInfo(); + + if (!FLI.CanLowerReturn) { + unsigned DemoteReg = FLI.DemoteRegister; + const Function *F = I.getParent()->getParent(); + + // Emit a store of the return value through the virtual register. + // Leave Outs empty so that LowerReturn won't try to load return + // registers the usual way. + SmallVector PtrValueVTs; + ComputeValueVTs(TLI, PointerType::getUnqual(F->getReturnType()), + PtrValueVTs); + + SDValue RetPtr = DAG.getRegister(DemoteReg, PtrValueVTs[0]); + SDValue RetOp = getValue(I.getOperand(0)); + SmallVector ValueVTs; - ComputeValueVTs(TLI, I.getOperand(i)->getType(), ValueVTs); + SmallVector Offsets; + ComputeValueVTs(TLI, I.getOperand(0)->getType(), ValueVTs, &Offsets); unsigned NumValues = ValueVTs.size(); - if (NumValues == 0) continue; - SDValue RetOp = getValue(I.getOperand(i)); - for (unsigned j = 0, f = NumValues; j != f; ++j) { - EVT VT = ValueVTs[j]; - - ISD::NodeType ExtendKind = ISD::ANY_EXTEND; + SmallVector Chains(NumValues); + EVT PtrVT = PtrValueVTs[0]; + for (unsigned i = 0; i != NumValues; ++i) + Chains[i] = DAG.getStore(Chain, getCurDebugLoc(), + SDValue(RetOp.getNode(), RetOp.getResNo() + i), + DAG.getNode(ISD::ADD, getCurDebugLoc(), PtrVT, RetPtr, + DAG.getConstant(Offsets[i], PtrVT)), + NULL, Offsets[i], false, 0); + Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), + MVT::Other, &Chains[0], NumValues); + } + else { + for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { + SmallVector ValueVTs; + ComputeValueVTs(TLI, I.getOperand(i)->getType(), ValueVTs); + unsigned NumValues = ValueVTs.size(); + if (NumValues == 0) continue; + + SDValue RetOp = getValue(I.getOperand(i)); + for (unsigned j = 0, f = NumValues; j != f; ++j) { + EVT VT = ValueVTs[j]; + + ISD::NodeType ExtendKind = ISD::ANY_EXTEND; + + const Function *F = I.getParent()->getParent(); + if (F->paramHasAttr(0, Attribute::SExt)) + ExtendKind = ISD::SIGN_EXTEND; + else if (F->paramHasAttr(0, Attribute::ZExt)) + ExtendKind = ISD::ZERO_EXTEND; + + // FIXME: C calling convention requires the return type to be promoted to + // at least 32-bit. But this is not necessary for non-C calling + // conventions. The frontend should mark functions whose return values + // require promoting with signext or zeroext attributes. + if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { + EVT MinVT = TLI.getRegisterType(*DAG.getContext(), MVT::i32); + if (VT.bitsLT(MinVT)) + VT = MinVT; + } - const Function *F = I.getParent()->getParent(); - if (F->paramHasAttr(0, Attribute::SExt)) - ExtendKind = ISD::SIGN_EXTEND; - else if (F->paramHasAttr(0, Attribute::ZExt)) - ExtendKind = ISD::ZERO_EXTEND; + unsigned NumParts = TLI.getNumRegisters(*DAG.getContext(), VT); + EVT PartVT = TLI.getRegisterType(*DAG.getContext(), VT); + SmallVector Parts(NumParts); + getCopyToParts(DAG, getCurDebugLoc(), + SDValue(RetOp.getNode(), RetOp.getResNo() + j), + &Parts[0], NumParts, PartVT, ExtendKind); + + // 'inreg' on function refers to return value + ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy(); + if (F->paramHasAttr(0, Attribute::InReg)) + Flags.setInReg(); + + // Propagate extension type if any + if (F->paramHasAttr(0, Attribute::SExt)) + Flags.setSExt(); + else if (F->paramHasAttr(0, Attribute::ZExt)) + Flags.setZExt(); - // FIXME: C calling convention requires the return type to be promoted to - // at least 32-bit. But this is not necessary for non-C calling - // conventions. The frontend should mark functions whose return values - // require promoting with signext or zeroext attributes. - if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { - EVT MinVT = TLI.getRegisterType(*DAG.getContext(), MVT::i32); - if (VT.bitsLT(MinVT)) - VT = MinVT; + for (unsigned i = 0; i < NumParts; ++i) + Outs.push_back(ISD::OutputArg(Flags, Parts[i], /*isfixed=*/true)); } - - unsigned NumParts = TLI.getNumRegisters(*DAG.getContext(), VT); - EVT PartVT = TLI.getRegisterType(*DAG.getContext(), VT); - SmallVector Parts(NumParts); - getCopyToParts(DAG, getCurDebugLoc(), - SDValue(RetOp.getNode(), RetOp.getResNo() + j), - &Parts[0], NumParts, PartVT, ExtendKind); - - // 'inreg' on function refers to return value - ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy(); - if (F->paramHasAttr(0, Attribute::InReg)) - Flags.setInReg(); - - // Propagate extension type if any - if (F->paramHasAttr(0, Attribute::SExt)) - Flags.setSExt(); - else if (F->paramHasAttr(0, Attribute::ZExt)) - Flags.setZExt(); - - for (unsigned i = 0; i < NumParts; ++i) - Outs.push_back(ISD::OutputArg(Flags, Parts[i], /*isfixed=*/true)); } } @@ -4453,15 +4486,52 @@ MachineBasicBlock *LandingPad) { const PointerType *PT = cast(CS.getCalledValue()->getType()); const FunctionType *FTy = cast(PT->getElementType()); + const Type *RetTy = FTy->getReturnType(); MachineModuleInfo *MMI = DAG.getMachineModuleInfo(); unsigned BeginLabel = 0, EndLabel = 0; TargetLowering::ArgListTy Args; TargetLowering::ArgListEntry Entry; Args.reserve(CS.arg_size()); - unsigned j = 1; + + // Check whether the function can return without sret-demotion. + SmallVector OutVTs; + SmallVector OutsFlags; + SmallVector Offsets; + getReturnInfo(RetTy, CS.getAttributes().getRetAttributes(), + OutVTs, OutsFlags, TLI, &Offsets); + + + bool CanLowerReturn = TLI.CanLowerReturn(CS.getCallingConv(), + FTy->isVarArg(), OutVTs, OutsFlags, DAG); + + SDValue DemoteStackSlot; + + if (!CanLowerReturn) { + uint64_t TySize = TLI.getTargetData()->getTypeAllocSize( + FTy->getReturnType()); + unsigned Align = TLI.getTargetData()->getPrefTypeAlignment( + FTy->getReturnType()); + MachineFunction &MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align); + const Type *StackSlotPtrType = PointerType::getUnqual(FTy->getReturnType()); + + DemoteStackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy()); + Entry.Node = DemoteStackSlot; + Entry.Ty = StackSlotPtrType; + Entry.isSExt = false; + Entry.isZExt = false; + Entry.isInReg = false; + Entry.isSRet = true; + Entry.isNest = false; + Entry.isByVal = false; + Entry.Alignment = Align; + Args.push_back(Entry); + RetTy = Type::getVoidTy(FTy->getContext()); + } + for (CallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end(); - i != e; ++i, ++j) { + i != e; ++i) { SDValue ArgNode = getValue(*i); Entry.Node = ArgNode; Entry.Ty = (*i)->getType(); @@ -4497,7 +4567,7 @@ isTailCall = false; std::pair Result = - TLI.LowerCallTo(getRoot(), CS.getType(), + TLI.LowerCallTo(getRoot(), RetTy, CS.paramHasAttr(0, Attribute::SExt), CS.paramHasAttr(0, Attribute::ZExt), FTy->isVarArg(), CS.paramHasAttr(0, Attribute::InReg), FTy->getNumParams(), @@ -4511,6 +4581,35 @@ "Null value expected with tail call!"); if (Result.first.getNode()) setValue(CS.getInstruction(), Result.first); + else if (!CanLowerReturn && Result.second.getNode()) { + // The instruction result is the result of loading from the + // hidden sret parameter. + SmallVector PVTs; + const Type *PtrRetTy = PointerType::getUnqual(FTy->getReturnType()); + + ComputeValueVTs(TLI, PtrRetTy, PVTs); + assert(PVTs.size() == 1 && "Pointers should fit in one register"); + EVT PtrVT = PVTs[0]; + unsigned NumValues = OutVTs.size(); + SmallVector Values(NumValues); + SmallVector Chains(NumValues); + + for (unsigned i = 0; i < NumValues; ++i) { + SDValue L = DAG.getLoad(OutVTs[i], getCurDebugLoc(), Result.second, + DAG.getNode(ISD::ADD, getCurDebugLoc(), PtrVT, DemoteStackSlot, + DAG.getConstant(Offsets[i], PtrVT)), + NULL, Offsets[i], false, 1); + Values[i] = L; + Chains[i] = L.getValue(1); + } + SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), + MVT::Other, &Chains[0], NumValues); + PendingLoads.push_back(Chain); + + setValue(CS.getInstruction(), DAG.getNode(ISD::MERGE_VALUES, + getCurDebugLoc(), DAG.getVTList(&OutVTs[0], NumValues), + &Values[0], NumValues)); + } // As a special case, a null chain means that a tail call has // been emitted and the DAG root is already updated. if (Result.second.getNode()) @@ -5779,17 +5878,32 @@ SDValue OldRoot = DAG.getRoot(); DebugLoc dl = SDL->getCurDebugLoc(); const TargetData *TD = TLI.getTargetData(); + SmallVector Ins; // Check whether the function can return without sret-demotion. SmallVector OutVTs; SmallVector OutsFlags; - getReturnInfo(&F, OutVTs, OutsFlags, TLI); - // For now, assert and bail out if it can't. - assert(TLI.CanLowerReturn(F.getCallingConv(), F.isVarArg(), OutVTs, OutsFlags, - DAG) && "Cannot fit return value in registers!"); + getReturnInfo(F.getReturnType(), F.getAttributes().getRetAttributes(), + OutVTs, OutsFlags, TLI); + FunctionLoweringInfo &FLI = DAG.getFunctionLoweringInfo(); + + FLI.CanLowerReturn = TLI.CanLowerReturn(F.getCallingConv(), F.isVarArg(), + OutVTs, OutsFlags, DAG); + if (!FLI.CanLowerReturn) { + // Put in an sret pointer parameter before all the other parameters. + SmallVector ValueVTs; + ComputeValueVTs(TLI, PointerType::getUnqual(F.getReturnType()), ValueVTs); + + // NOTE: Assuming that a pointer will never break down to more than one VT + // or one register. + ISD::ArgFlagsTy Flags; + Flags.setSRet(); + EVT RegisterVT = TLI.getRegisterType(*CurDAG->getContext(), ValueVTs[0]); + ISD::InputArg RetArg(Flags, RegisterVT, true); + Ins.push_back(RetArg); + } // Set up the incoming argument description vector. - SmallVector Ins; unsigned Idx = 1; for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I, ++Idx) { @@ -5867,6 +5981,28 @@ // Set up the argument values. unsigned i = 0; Idx = 1; + if (!FLI.CanLowerReturn) { + // Create a virtual register for the sret pointer, and put in a copy + // from the sret argument into it. + SmallVector ValueVTs; + ComputeValueVTs(TLI, PointerType::getUnqual(F.getReturnType()), ValueVTs); + EVT VT = ValueVTs[0]; + EVT RegVT = TLI.getRegisterType(*CurDAG->getContext(), VT); + ISD::NodeType AssertOp = ISD::DELETED_NODE; + SDValue ArgValue = getCopyFromParts(DAG, dl, &InVals[0], 1, RegVT, + VT, AssertOp); + + MachineFunction& MF = SDL->DAG.getMachineFunction(); + MachineRegisterInfo& RegInfo = MF.getRegInfo(); + unsigned SRetReg = RegInfo.createVirtualRegister(TLI.getRegClassFor(RegVT)); + FLI.DemoteRegister = SRetReg; + NewRoot = SDL->DAG.getCopyToReg(NewRoot, SDL->getCurDebugLoc(), SRetReg, ArgValue); + DAG.setRoot(NewRoot); + + // i indexes lowered arguments. Bump it past the hidden sret argument. + // Idx indexes LLVM arguments. Don't touch it. + ++i; + } for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I, ++Idx) { SmallVector ArgValues; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h?rev=86876&r1=86875&r2=86876&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h Wed Nov 11 13:59:24 2009 @@ -90,6 +90,14 @@ MachineFunction *MF; MachineRegisterInfo *RegInfo; + /// CanLowerReturn - true iff the function's return value can be lowered to + /// registers. + bool CanLowerReturn; + + /// DemoteRegister - if CanLowerReturn is false, DemoteRegister is a vreg + /// allocated to hold a pointer to the hidden sret parameter. + unsigned DemoteRegister; + explicit FunctionLoweringInfo(TargetLowering &TLI); /// set - Initialize this FunctionLoweringInfo with the given Function Added: llvm/trunk/test/CodeGen/X86/bigstructret.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bigstructret.ll?rev=86876&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/bigstructret.ll (added) +++ llvm/trunk/test/CodeGen/X86/bigstructret.ll Wed Nov 11 13:59:24 2009 @@ -0,0 +1,17 @@ +; RUN: llc < %s -march=x86 -o %t +; RUN: grep "movl .24601, 12(%ecx)" %t +; RUN: grep "movl .48, 8(%ecx)" %t +; RUN: grep "movl .24, 4(%ecx)" %t +; RUN: grep "movl .12, (%ecx)" %t + +%0 = type { i32, i32, i32, i32 } + +define internal fastcc %0 @ReturnBigStruct() nounwind readnone { +entry: + %0 = insertvalue %0 zeroinitializer, i32 12, 0 + %1 = insertvalue %0 %0, i32 24, 1 + %2 = insertvalue %0 %1, i32 48, 2 + %3 = insertvalue %0 %2, i32 24601, 3 + ret %0 %3 +} + From vkutuzov at accesssoftek.com Wed Nov 11 14:16:07 2009 From: vkutuzov at accesssoftek.com (Viktor Kutuzov) Date: Wed, 11 Nov 2009 12:16:07 -0800 Subject: [llvm-commits] [PATCH] LTO code generator options: --verbose References: <6AE1604EE3EC5F4296C096518C6B77EEF99C4FAA@mail.accesssoftek.com><7383326612F04B4DA85C26A2C9A4E6D4@andreic6e7fe55><4C3AAB5F-812D-4811-A1EE-DEF04E0F29EE@apple.com> <214DD1AE30F746F5B0086F4773D23D32@andreic6e7fe55> <4AFB16E0.9040103@mxc.ca> Message-ID: <8CBDD792C4CB4525B8689033B22886D9@andreic6e7fe55> I have been thinking of how people will set up and maintain complex builds with our tools. Once in a while something will go wrong and it should be a way to figure out what's going on behind the scene. The idea is to have a special "verbose" mode for builds trouble shooting. It is a run-time mode, not a debug; the toolchain does the regular things but provides detailed messages along the way. Gold plugin runs other tools, so from this perspective it is helpful to be able to see what exact program get ran with what exact parameters. I planned to add passing the verbose flag (if set) down to the toolchain as well, just wanted to separate patches. Does it make sense? Viktor ----- Original Message ----- From: "Nick Lewycky" To: "Viktor Kutuzov" Cc: "Eric Christopher" ; "Commit Messages and Patches for LLVM" Sent: Wednesday, November 11, 2009 11:56 AM Subject: Re: [llvm-commits] [PATCH] LTO code generator options: --verbose Viktor Kutuzov wrote: > Please find attached the patch without cosmetic changes. Why do you need this? Or rather, when would a user want to specify this? If this is just debugging info, why not use DEBUG() from llvm/Support/Debug.h? Nick > Best regards, > Viktor > > ----- Original Message ----- From: "Eric Christopher" > To: "Viktor Kutuzov" > Cc: "Commit Messages and Patches for LLVM" > Sent: Tuesday, November 10, 2009 1:15 PM > Subject: Re: [llvm-commits] [PATCH] LTO code generator options: --verbose > > > > On Nov 10, 2009, at 1:10 PM, Viktor Kutuzov wrote: > >> > > It'd be easier to look at if there were less cosmetic changes in the > patch. That said, what do you expect this will add? > > -eric > > > ------------------------------------------------------------------------ > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Wed Nov 11 14:54:49 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 11 Nov 2009 12:54:49 -0800 Subject: [llvm-commits] [llvm] r86791 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp In-Reply-To: <41DF73EA-6ED0-44BB-9084-D8366E11A928@apple.com> References: <200911110247.nAB2lJjM014802@zion.cs.uiuc.edu> <90A068C9-E8C3-4C2D-B186-838F68F053C0@apple.com> <41DF73EA-6ED0-44BB-9084-D8366E11A928@apple.com> Message-ID: <868FA2F9-9BD6-4370-9CF4-4A71E29F2868@apple.com> On Nov 11, 2009, at 9:42 AM, Bob Wilson wrote: > > On Nov 11, 2009, at 9:22 AM, Jim Grosbach wrote: >> >> Why was the code placement opt unsafe for arm before? I don't recall >> the history there. > > If I remember correctly, it was running after ARMConstantIslandPass when it is not safe to change the size or position of anything. This has been fixed. Evan From evan.cheng at apple.com Wed Nov 11 15:23:40 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 11 Nov 2009 13:23:40 -0800 Subject: [llvm-commits] [llvm] r86791 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp In-Reply-To: References: <200911110247.nAB2lJjM014802@zion.cs.uiuc.edu> <90A068C9-E8C3-4C2D-B186-838F68F053C0@apple.com> Message-ID: <98E76E15-435B-473F-877F-F55CC4C514A9@apple.com> On Nov 11, 2009, at 9:22 AM, Jim Grosbach wrote: > Yeah, it definitely should be moved. That's one of the things I'm going to do this morning. > > We could do it in the placement optimization pass, but I'm a bit hesitant at this point since a fair bit of the information we may use for determining how and whether to make transformations will be target specific. The ranges of the TB[BH] instructions being the most straightforward example. That may be handleable via target hooks or something, though. Once we have a better handle on the specifics of the heuristics, that should be more apparent. Your concerns are valid. The only reason I think doing it in BB placement is more targets might benefit if any jump taken is to the same direction. It might help branch prediction for more than just ARM. Evan > > Why was the code placement opt unsafe for arm before? I don't recall the history there. > > -Jim > > On Nov 10, 2009, at 11:05 PM, Evan Cheng wrote: > >> Is this done during OptimizeThumb2JumpTables? Then I don't think that would work. It will mess up constant island placements. Perhaps this has to be done before the constant islands part? Or even in the bb placement optimization pass (which should be safe to turn on for ARM now)? >> >> Evan >> >> On Nov 10, 2009, at 6:47 PM, Jim Grosbach wrote: >> >>> Author: grosbach >>> Date: Tue Nov 10 20:47:19 2009 >>> New Revision: 86791 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=86791&view=rev >>> Log: >>> >>> The TBB and TBH instructions for Thumb2 are really handy for jump tables, but >>> can only branch forward. To best take advantage of them, we'd like to adjust >>> the basic blocks around a bit when reasonable. This patch puts basics in place >>> to do that, with a super-simple algorithm for backwards jump table targets that >>> creates a new branch after the jump table which branches backwards. Real >>> heuristics for reordering blocks or other modifications rather than inserting >>> branches will follow. >>> >>> >>> Modified: >>> llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp >>> >>> Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=86791&r1=86790&r2=86791&view=diff >>> >>> ============================================================================== >>> --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) >>> +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Tue Nov 10 20:47:19 2009 >>> @@ -31,6 +31,7 @@ >>> #include "llvm/ADT/SmallVector.h" >>> #include "llvm/ADT/STLExtras.h" >>> #include "llvm/ADT/Statistic.h" >>> +#include "llvm/Support/CommandLine.h" >>> #include >>> using namespace llvm; >>> >>> @@ -42,6 +43,12 @@ >>> STATISTIC(NumT2CPShrunk, "Number of Thumb2 constantpool instructions shrunk"); >>> STATISTIC(NumT2BrShrunk, "Number of Thumb2 immediate branches shrunk"); >>> STATISTIC(NumCBZ, "Number of CBZ / CBNZ formed"); >>> +STATISTIC(NumJTMoved, "Number of jump table destination blocks moved"); >>> + >>> + >>> +static cl::opt >>> +AdjustJumpTableBlocks("arm-adjust-jump-tables", cl::Hidden, cl::init(false), >>> + cl::desc("Adjust basic block layout to better use TB[BH]")); >>> >>> namespace { >>> /// ARMConstantIslands - Due to limited PC-relative displacements, ARM >>> @@ -202,6 +209,8 @@ >>> bool OptimizeThumb2Instructions(MachineFunction &MF); >>> bool OptimizeThumb2Branches(MachineFunction &MF); >>> bool OptimizeThumb2JumpTables(MachineFunction &MF); >>> + MachineBasicBlock *AdjustJTTargetBlockForward(MachineBasicBlock *BB, >>> + MachineBasicBlock *JTBB); >>> >>> unsigned GetOffsetOf(MachineInstr *MI) const; >>> void dumpBBs(); >>> @@ -1560,7 +1569,7 @@ >>> >>> // FIXME: After the tables are shrunk, can we get rid some of the >>> // constantpool tables? >>> - const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); >>> + MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); >>> const std::vector &JT = MJTI->getJumpTables(); >>> for (unsigned i = 0, e = T2JumpTables.size(); i != e; ++i) { >>> MachineInstr *MI = T2JumpTables[i]; >>> @@ -1571,10 +1580,33 @@ >>> unsigned JTI = JTOP.getIndex(); >>> assert(JTI < JT.size()); >>> >>> - bool ByteOk = true; >>> - bool HalfWordOk = true; >>> + // We prefer if target blocks for the jump table come after the jump >>> + // instruction so we can use TB[BH]. Loop through the target blocks >>> + // and try to adjust them such that that's true. >>> unsigned JTOffset = GetOffsetOf(MI) + 4; >>> const std::vector &JTBBs = JT[JTI].MBBs; >>> + if (AdjustJumpTableBlocks) { >>> + for (unsigned j = 0, ee = JTBBs.size(); j != ee; ++j) { >>> + MachineBasicBlock *MBB = JTBBs[j]; >>> + unsigned DstOffset = BBOffsets[MBB->getNumber()]; >>> + >>> + if (DstOffset < JTOffset) { >>> + // The destination precedes the switch. Try to move the block forward >>> + // so we have a positive offset. >>> + MachineBasicBlock *NewBB = >>> + AdjustJTTargetBlockForward(MBB, MI->getParent()); >>> + if (NewBB) { >>> + MJTI->ReplaceMBBInJumpTables(JTBBs[j], NewBB); >>> + JTOffset = GetOffsetOf(MI) + 4; >>> + DstOffset = BBOffsets[MBB->getNumber()]; >>> + } >>> + } >>> + } >>> + } >>> + >>> + bool ByteOk = true; >>> + bool HalfWordOk = true; >>> + JTOffset = GetOffsetOf(MI) + 4; >>> for (unsigned j = 0, ee = JTBBs.size(); j != ee; ++j) { >>> MachineBasicBlock *MBB = JTBBs[j]; >>> unsigned DstOffset = BBOffsets[MBB->getNumber()]; >>> @@ -1660,3 +1692,64 @@ >>> >>> return MadeChange; >>> } >>> + >>> +MachineBasicBlock *ARMConstantIslands:: >>> +AdjustJTTargetBlockForward(MachineBasicBlock *BB, MachineBasicBlock *JTBB) >>> +{ >>> + MachineFunction &MF = *BB->getParent(); >>> + >>> + // FIXME: For now, instead of moving the block, we'll create a new block >>> + // immediate following the jump that's an unconditional branch to the >>> + // actual target. This is obviously not what we want for a real solution, >>> + // but it's useful for proof of concept, and it may be a useful fallback >>> + // later for cases where we otherwise can't move a block. >>> + >>> + // Create a new MBB for the code after the jump BB. >>> + MachineBasicBlock *NewBB = >>> + MF.CreateMachineBasicBlock(JTBB->getBasicBlock()); >>> + MachineFunction::iterator MBBI = JTBB; ++MBBI; >>> + MF.insert(MBBI, NewBB); >>> + >>> + // Add an unconditional branch from NewBB to BB. >>> + // There doesn't seem to be meaningful DebugInfo available; this doesn't >>> + // correspond directly to anything in the source. >>> + assert (isThumb2 && "Adjusting for TB[BH] but not in Thumb2?"); >>> + BuildMI(NewBB, DebugLoc::getUnknownLoc(), TII->get(ARM::t2B)).addMBB(BB); >>> + >>> + // Update the CFG. >>> + NewBB->addSuccessor(BB); >>> + JTBB->removeSuccessor(BB); >>> + JTBB->addSuccessor(NewBB); >>> + >>> + // Update internal data structures to account for the newly inserted MBB. >>> + // This is almost the same as UpdateForInsertedWaterBlock, except that >>> + // the Water goes after OrigBB, not NewBB. >>> + MF.RenumberBlocks(NewBB); >>> + >>> + // Insert a size into BBSizes to align it properly with the (newly >>> + // renumbered) block numbers. >>> + BBSizes.insert(BBSizes.begin()+NewBB->getNumber(), 0); >>> + >>> + // Likewise for BBOffsets. >>> + BBOffsets.insert(BBOffsets.begin()+NewBB->getNumber(), 0); >>> + >>> + // Figure out how large the first NewMBB is. >>> + unsigned NewBBSize = 0; >>> + for (MachineBasicBlock::iterator I = NewBB->begin(), E = NewBB->end(); >>> + I != E; ++I) >>> + NewBBSize += TII->GetInstSizeInBytes(I); >>> + >>> + unsigned NewBBI = NewBB->getNumber(); >>> + unsigned JTBBI = JTBB->getNumber(); >>> + // Set the size of NewBB in BBSizes. >>> + BBSizes[NewBBI] = NewBBSize; >>> + >>> + // ...and adjust BBOffsets for NewBB accordingly. >>> + BBOffsets[NewBBI] = BBOffsets[JTBBI] + BBSizes[JTBBI]; >>> + >>> + // All BBOffsets following these blocks must be modified. >>> + AdjustBBOffsetsAfter(NewBB, 4); >>> + >>> + ++NumJTMoved; >>> + return NewBB; >>> +} >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > From bruno.cardoso at gmail.com Wed Nov 11 15:47:30 2009 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Wed, 11 Nov 2009 19:47:30 -0200 Subject: [llvm-commits] [llvm] r86651 - /llvm/trunk/lib/Target/Mips/MipsInstrFPU.td In-Reply-To: References: <200911100235.nAA2ZERO012563@zion.cs.uiuc.edu> Message-ID: <275e64e40911111347w49b62e56l9b730629aa1be39d@mail.gmail.com> Hi Chris, On Tue, Nov 10, 2009 at 3:16 AM, Chris Lattner wrote: > > On Nov 9, 2009, at 6:35 PM, Bruno Cardoso Lopes wrote: > >> Author: bruno >> Date: Mon Nov ?9 20:35:13 2009 >> New Revision: 86651 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=86651&view=rev >> Log: >> Fix PR5445 > > Hey Bruno, > > FYI -0.0 is not the same as 0.0. Yep, I forgot that, I'll do the right IEEE 754 solution, thanks! :) > -Chris > >> >> Modified: >> ? llvm/trunk/lib/Target/Mips/MipsInstrFPU.td >> >> Modified: llvm/trunk/lib/Target/Mips/MipsInstrFPU.td >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrFPU.td?rev=86651&r1=86650&r2=86651&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> ====================================================================== >> --- llvm/trunk/lib/Target/Mips/MipsInstrFPU.td (original) >> +++ llvm/trunk/lib/Target/Mips/MipsInstrFPU.td Mon Nov ?9 20:35:13 2009 >> @@ -281,7 +281,7 @@ >> // Floating Point Patterns >> //===----------------------------------------------------------------------===// >> def fpimm0 : PatLeaf<(fpimm), [{ >> - ?return N->isExactlyValue(+0.0); >> + ?return N->isExactlyValue(+0.0) || N->isExactlyValue(-0.0); >> }]>; >> >> def : Pat<(f32 fpimm0), (MTC1 ZERO)>; >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -- Bruno Cardoso Lopes http://www.brunocardoso.cc From gohman at apple.com Wed Nov 11 15:57:02 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 11 Nov 2009 21:57:02 -0000 Subject: [llvm-commits] [llvm] r86885 - in /llvm/trunk/lib/CodeGen: BranchFolding.cpp BranchFolding.h Message-ID: <200911112157.nABLv2b4007774@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 11 15:57:02 2009 New Revision: 86885 URL: http://llvm.org/viewvc/llvm-project?rev=86885&view=rev Log: Promote MergePotentialsElt and SameTailElt to be regular classes instead of typedefs for std::pair. This simplifies the type of SameTails, which previously was std::vector >::iterator, MachineBasicBlock::iterator> Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp llvm/trunk/lib/CodeGen/BranchFolding.h Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=86885&r1=86884&r2=86885&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Wed Nov 11 15:57:02 2009 @@ -429,24 +429,24 @@ TII->InsertBranch(*CurMBB, SuccBB, NULL, SmallVector()); } -static bool MergeCompare(const std::pair &p, - const std::pair &q) { - if (p.first < q.first) - return true; - else if (p.first > q.first) - return false; - else if (p.second->getNumber() < q.second->getNumber()) - return true; - else if (p.second->getNumber() > q.second->getNumber()) - return false; - else { - // _GLIBCXX_DEBUG checks strict weak ordering, which involves comparing - // an object with itself. +bool +BranchFolder::MergePotentialsElt::operator<(const MergePotentialsElt &o) const { + if (getHash() < o.getHash()) + return true; + else if (getHash() > o.getHash()) + return false; + else if (getBlock()->getNumber() < o.getBlock()->getNumber()) + return true; + else if (getBlock()->getNumber() > o.getBlock()->getNumber()) + return false; + else { + // _GLIBCXX_DEBUG checks strict weak ordering, which involves comparing + // an object with itself. #ifndef _GLIBCXX_DEBUG - llvm_unreachable("Predecessor appears twice"); + llvm_unreachable("Predecessor appears twice"); #endif - return false; - } + return false; + } } /// CountTerminators - Count the number of terminators in the given @@ -537,22 +537,23 @@ MPIterator HighestMPIter = prior(MergePotentials.end()); for (MPIterator CurMPIter = prior(MergePotentials.end()), B = MergePotentials.begin(); - CurMPIter!=B && CurMPIter->first == CurHash; + CurMPIter!=B && CurMPIter->getHash() == CurHash; --CurMPIter) { - for (MPIterator I = prior(CurMPIter); I->first == CurHash ; --I) { + for (MPIterator I = prior(CurMPIter); I->getHash() == CurHash ; --I) { unsigned CommonTailLen; - if (ProfitableToMerge(CurMPIter->second, I->second, minCommonTailLength, + if (ProfitableToMerge(CurMPIter->getBlock(), I->getBlock(), + minCommonTailLength, CommonTailLen, TrialBBI1, TrialBBI2, SuccBB, PredBB)) { if (CommonTailLen > maxCommonTailLength) { SameTails.clear(); maxCommonTailLength = CommonTailLen; HighestMPIter = CurMPIter; - SameTails.push_back(std::make_pair(CurMPIter, TrialBBI1)); + SameTails.push_back(SameTailElt(CurMPIter, TrialBBI1)); } if (HighestMPIter == CurMPIter && CommonTailLen == maxCommonTailLength) - SameTails.push_back(std::make_pair(I, TrialBBI2)); + SameTails.push_back(SameTailElt(I, TrialBBI2)); } if (I == B) break; @@ -568,16 +569,16 @@ MachineBasicBlock* PredBB) { MPIterator CurMPIter, B; for (CurMPIter = prior(MergePotentials.end()), B = MergePotentials.begin(); - CurMPIter->first == CurHash; + CurMPIter->getHash() == CurHash; --CurMPIter) { // Put the unconditional branch back, if we need one. - MachineBasicBlock *CurMBB = CurMPIter->second; + MachineBasicBlock *CurMBB = CurMPIter->getBlock(); if (SuccBB && CurMBB != PredBB) FixTail(CurMBB, SuccBB, TII); if (CurMPIter == B) break; } - if (CurMPIter->first!=CurHash) + if (CurMPIter->getHash() != CurHash) CurMPIter++; MergePotentials.erase(CurMPIter, MergePotentials.end()); } @@ -590,29 +591,30 @@ unsigned TimeEstimate = ~0U; for (i=0, commonTailIndex=0; isecond == PredBB) { + if (SameTails[i].getBlock() == PredBB) { commonTailIndex = i; break; } // Otherwise, make a (fairly bogus) choice based on estimate of // how long it will take the various blocks to execute. - unsigned t = EstimateRuntime(SameTails[i].first->second->begin(), - SameTails[i].second); + unsigned t = EstimateRuntime(SameTails[i].getBlock()->begin(), + SameTails[i].getTailStartPos()); if (t <= TimeEstimate) { TimeEstimate = t; commonTailIndex = i; } } - MachineBasicBlock::iterator BBI = SameTails[commonTailIndex].second; - MachineBasicBlock *MBB = SameTails[commonTailIndex].first->second; + MachineBasicBlock::iterator BBI = + SameTails[commonTailIndex].getTailStartPos(); + MachineBasicBlock *MBB = SameTails[commonTailIndex].getBlock(); DEBUG(errs() << "\nSplitting BB#" << MBB->getNumber() << ", size " << maxCommonTailLength); MachineBasicBlock *newMBB = SplitMBBAt(*MBB, BBI); - SameTails[commonTailIndex].first->second = newMBB; - SameTails[commonTailIndex].second = newMBB->begin(); + SameTails[commonTailIndex].setBlock(newMBB); + SameTails[commonTailIndex].setTailStartPos(newMBB->begin()); // If we split PredBB, newMBB is the new predecessor. if (PredBB == MBB) @@ -641,22 +643,22 @@ // new branching and as such are very likely to be profitable. if (SuccBB) { if (SuccBB->pred_size() == MergePotentials.size() && - !MergePotentials[0].second->empty()) { + !MergePotentials[0].getBlock()->empty()) { // If all the predecessors have at least one tail instruction in common, // merging is very likely to be a win since it won't require an increase // in static branches, and it will decrease the static instruction count. bool AllPredsMatch = true; MachineBasicBlock::iterator FirstNonTerm; - unsigned MinNumTerms = CountTerminators(MergePotentials[0].second, + unsigned MinNumTerms = CountTerminators(MergePotentials[0].getBlock(), FirstNonTerm); - if (FirstNonTerm != MergePotentials[0].second->end()) { + if (FirstNonTerm != MergePotentials[0].getBlock()->end()) { for (unsigned i = 1, e = MergePotentials.size(); i != e; ++i) { MachineBasicBlock::iterator OtherFirstNonTerm; - unsigned NumTerms = CountTerminators(MergePotentials[0].second, + unsigned NumTerms = CountTerminators(MergePotentials[0].getBlock(), OtherFirstNonTerm); if (NumTerms < MinNumTerms) MinNumTerms = NumTerms; - if (OtherFirstNonTerm == MergePotentials[i].second->end() || + if (OtherFirstNonTerm == MergePotentials[i].getBlock()->end() || OtherFirstNonTerm->isIdenticalTo(FirstNonTerm)) { AllPredsMatch = false; break; @@ -672,7 +674,7 @@ DEBUG(errs() << "\nTryTailMergeBlocks: "; for (unsigned i = 0, e = MergePotentials.size(); i != e; ++i) - errs() << "BB#" << MergePotentials[i].second->getNumber() + errs() << "BB#" << MergePotentials[i].getBlock()->getNumber() << (i == e-1 ? "" : ", "); errs() << "\n"; if (SuccBB) { @@ -688,11 +690,11 @@ // Sort by hash value so that blocks with identical end sequences sort // together. - std::stable_sort(MergePotentials.begin(), MergePotentials.end(),MergeCompare); + std::stable_sort(MergePotentials.begin(), MergePotentials.end()); // Walk through equivalence sets looking for actual exact matches. while (MergePotentials.size() > 1) { - unsigned CurHash = MergePotentials.back().first; + unsigned CurHash = MergePotentials.back().getHash(); // Build SameTails, identifying the set of blocks with this hash code // and with the maximum number of instructions in common. @@ -711,31 +713,30 @@ // block, which we can't jump to), we can treat all blocks with this same // tail at once. Use PredBB if that is one of the possibilities, as that // will not introduce any extra branches. - MachineBasicBlock *EntryBB = MergePotentials.begin()->second-> - getParent()->begin(); - unsigned int commonTailIndex, i; - for (commonTailIndex=SameTails.size(), i=0; isecond; + MachineBasicBlock *EntryBB = MergePotentials.begin()->getBlock()-> + getParent()->begin(); + unsigned commonTailIndex = SameTails.size(); + for (unsigned i=0; ibegin() == SameTails[i].second) + if (MBB->begin() == SameTails[i].getTailStartPos()) commonTailIndex = i; } if (commonTailIndex == SameTails.size() || - (SameTails[commonTailIndex].first->second == PredBB && - SameTails[commonTailIndex].first->second->begin() != - SameTails[i].second)) { + (SameTails[commonTailIndex].getBlock() == PredBB && + !SameTails[commonTailIndex].tailIsWholeBlock())) { // None of the blocks consist entirely of the common tail. // Split a block so that one does. commonTailIndex = CreateCommonTailOnlyBlock(PredBB, maxCommonTailLength); } - MachineBasicBlock *MBB = SameTails[commonTailIndex].first->second; + MachineBasicBlock *MBB = SameTails[commonTailIndex].getBlock(); // MBB is common tail. Adjust all other BB's to jump to this one. // Traversal must be forwards so erases work. DEBUG(errs() << "\nUsing common tail in BB#" << MBB->getNumber() @@ -743,12 +744,12 @@ for (unsigned int i=0, e = SameTails.size(); i != e; ++i) { if (commonTailIndex == i) continue; - DEBUG(errs() << "BB#" << SameTails[i].first->second->getNumber() + DEBUG(errs() << "BB#" << SameTails[i].getBlock()->getNumber() << (i == e-1 ? "" : ", ")); // Hack the end off BB i, making it jump to BB commonTailIndex instead. - ReplaceTailWithBranchTo(SameTails[i].second, MBB); + ReplaceTailWithBranchTo(SameTails[i].getTailStartPos(), MBB); // BB i is no longer a predecessor of SuccBB; remove it from the worklist. - MergePotentials.erase(SameTails[i].first); + MergePotentials.erase(SameTails[i].getMPIter()); } DEBUG(errs() << "\n"); // We leave commonTailIndex in the worklist in case there are other blocks @@ -768,7 +769,7 @@ MergePotentials.clear(); for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { if (I->succ_empty()) - MergePotentials.push_back(std::make_pair(HashEndOfMBB(I, 2U), I)); + MergePotentials.push_back(MergePotentialsElt(HashEndOfMBB(I, 2U), I)); } // See if we can do any tail merging on those. @@ -854,7 +855,8 @@ // reinsert conditional branch only, for now TII->InsertBranch(*PBB, (TBB == IBB) ? FBB : TBB, 0, NewCond); } - MergePotentials.push_back(std::make_pair(HashEndOfMBB(PBB, 1U), *P)); + MergePotentials.push_back(MergePotentialsElt(HashEndOfMBB(PBB, 1U), + *P)); } } if (MergePotentials.size() >= 2) @@ -863,8 +865,8 @@ // The 1 below can occur as a result of removing blocks in TryTailMergeBlocks. PredBB = prior(I); // this may have been changed in TryTailMergeBlocks if (MergePotentials.size() == 1 && - MergePotentials.begin()->second != PredBB) - FixTail(MergePotentials.begin()->second, IBB, TII); + MergePotentials.begin()->getBlock() != PredBB) + FixTail(MergePotentials.begin()->getBlock(), IBB, TII); } } return MadeChange; Modified: llvm/trunk/lib/CodeGen/BranchFolding.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.h?rev=86885&r1=86884&r2=86885&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.h (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.h Wed Nov 11 15:57:02 2009 @@ -30,11 +30,58 @@ const TargetRegisterInfo *tri, MachineModuleInfo *mmi); private: - typedef std::pair MergePotentialsElt; + class MergePotentialsElt { + unsigned Hash; + MachineBasicBlock *Block; + public: + MergePotentialsElt(unsigned h, MachineBasicBlock *b) + : Hash(h), Block(b) {} + + unsigned getHash() const { return Hash; } + MachineBasicBlock *getBlock() const { return Block; } + + void setBlock(MachineBasicBlock *MBB) { + Block = MBB; + } + + bool operator<(const MergePotentialsElt &) const; + }; typedef std::vector::iterator MPIterator; std::vector MergePotentials; - typedef std::pair SameTailElt; + class SameTailElt { + MPIterator MPIter; + MachineBasicBlock::iterator TailStartPos; + public: + SameTailElt(MPIterator mp, MachineBasicBlock::iterator tsp) + : MPIter(mp), TailStartPos(tsp) {} + + MPIterator getMPIter() const { + return MPIter; + } + MergePotentialsElt &getMergePotentialsElt() const { + return *getMPIter(); + } + MachineBasicBlock::iterator getTailStartPos() const { + return TailStartPos; + } + unsigned getHash() const { + return getMergePotentialsElt().getHash(); + } + MachineBasicBlock *getBlock() const { + return getMergePotentialsElt().getBlock(); + } + bool tailIsWholeBlock() const { + return TailStartPos == getBlock()->begin(); + } + + void setBlock(MachineBasicBlock *MBB) { + getMergePotentialsElt().setBlock(MBB); + } + void setTailStartPos(MachineBasicBlock::iterator Pos) { + TailStartPos = Pos; + } + }; std::vector SameTails; bool EnableTailMerge; From sabre at nondot.org Wed Nov 11 16:31:38 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 22:31:38 -0000 Subject: [llvm-commits] [llvm] r86886 - /llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200911112231.nABMVcqO009084@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 11 16:31:38 2009 New Revision: 86886 URL: http://llvm.org/viewvc/llvm-project?rev=86886&view=rev Log: pass TD into a SimplifyCmpInst call. Add another case that uses LVI info when -enable-jump-threading-lvi is passed. Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86886&r1=86885&r2=86886&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Wed Nov 11 16:31:38 2009 @@ -361,7 +361,7 @@ Value *LHS = PN->getIncomingValue(i); Value *RHS = Cmp->getOperand(1)->DoPHITranslation(BB, PredBB); - Value *Res = SimplifyCmpInst(Cmp->getPredicate(), LHS, RHS); + Value *Res = SimplifyCmpInst(Cmp->getPredicate(), LHS, RHS, TD); if (Res == 0) continue; if (isa(Res)) @@ -373,8 +373,29 @@ return !Result.empty(); } - // TODO: We could also recurse to see if we can determine constants another - // way. + + // If comparing a live-in value against a constant, see if we know the + // live-in value on any predecessors. + if (LVI && isa(Cmp->getOperand(1)) && + (!isa(Cmp->getOperand(0)) || + cast(Cmp->getOperand(0))->getParent() != BB)) { + Constant *RHSCst = cast(Cmp->getOperand(1)); + + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { + // If the value is known by LazyValueInfo to be a constant in a + // predecessor, use that information to try to thread this block. + Constant *PredCst = LVI->getConstant(Cmp->getOperand(0), *PI); + if (PredCst == 0) + continue; + + // Constant fold the compare. + Value *Res = SimplifyCmpInst(Cmp->getPredicate(), PredCst, RHSCst, TD); + if (isa(Res) || isa(Res)) + Result.push_back(std::make_pair(dyn_cast(Res), *PI)); + } + + return !Result.empty(); + } } return false; } From sabre at nondot.org Wed Nov 11 16:48:44 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 22:48:44 -0000 Subject: [llvm-commits] [llvm] r86889 - /llvm/trunk/lib/Analysis/LazyValueInfo.cpp Message-ID: <200911112248.nABMmiJu009704@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 11 16:48:44 2009 New Revision: 86889 URL: http://llvm.org/viewvc/llvm-project?rev=86889&view=rev Log: make LazyValueInfo actually to some stuff. This isn't very tested but improves strswitch. Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=86889&r1=86888&r2=86889&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Wed Nov 11 16:48:44 2009 @@ -17,6 +17,9 @@ #include "llvm/Instructions.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Target/TargetData.h" +#include "llvm/Support/CFG.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" using namespace llvm; @@ -58,6 +61,12 @@ public: LVILatticeVal() : Val(0, undefined) {} + static LVILatticeVal get(Constant *C) { + LVILatticeVal Res; + Res.markConstant(C); + return Res; + } + bool isUndefined() const { return Val.getInt() == undefined; } bool isConstant() const { return Val.getInt() == constant; } bool isOverdefined() const { return Val.getInt() == overdefined; } @@ -94,12 +103,34 @@ Val.setInt(constant); assert(V && "Marking constant with NULL"); Val.setPointer(V); + return true; + } + + /// mergeIn - Merge the specified lattice value into this one, updating this + /// one and returning true if anything changed. + bool mergeIn(const LVILatticeVal &RHS) { + if (RHS.isUndefined() || isOverdefined()) return false; + if (RHS.isOverdefined()) return markOverdefined(); + + // RHS must be a constant, we must be undef or constant. + if (isConstant() && getConstant() != RHS.getConstant()) + return markOverdefined(); + return markConstant(RHS.getConstant()); } }; } // end anonymous namespace. +namespace llvm { +raw_ostream &operator<<(raw_ostream &OS, const LVILatticeVal &Val) { + if (Val.isUndefined()) + return OS << "undefined"; + if (Val.isOverdefined()) + return OS << "overdefined"; + return OS << "constant<" << *Val.getConstant() << '>'; +} +} //===----------------------------------------------------------------------===// // LazyValueInfo Impl @@ -115,6 +146,127 @@ // No caching yet. } +static LVILatticeVal GetValueInBlock(Value *V, BasicBlock *BB, + DenseMap &); + +static LVILatticeVal GetValueOnEdge(Value *V, BasicBlock *BBFrom, + BasicBlock *BBTo, + DenseMap &BlockVals) { + // FIXME: Pull edge logic out of jump threading. + + + if (BranchInst *BI = dyn_cast(BBFrom->getTerminator())) { + // If this is a conditional branch and only one successor goes to BBTo, then + // we maybe able to infer something from the condition. + if (BI->isConditional() && + BI->getSuccessor(0) != BI->getSuccessor(1)) { + bool isTrueDest = BI->getSuccessor(0) == BBTo; + assert(BI->getSuccessor(!isTrueDest) == BBTo && + "BBTo isn't a successor of BBFrom"); + + // If V is the condition of the branch itself, then we know exactly what + // it is. + if (BI->getCondition() == V) + return LVILatticeVal::get(ConstantInt::get( + Type::getInt1Ty(V->getContext()), isTrueDest)); + + // If the condition of the branch is an equality comparison, we may be + // able to infer the value. + if (ICmpInst *ICI = dyn_cast(BI->getCondition())) + if (ICI->isEquality() && ICI->getOperand(0) == V && + isa(ICI->getOperand(1))) { + // We know that V has the RHS constant if this is a true SETEQ or + // false SETNE. + if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ)) + return LVILatticeVal::get(cast(ICI->getOperand(1))); + } + } + } + + // TODO: Info from switch. + + + // Otherwise see if the value is known in the block. + return GetValueInBlock(V, BBFrom, BlockVals); +} + +static LVILatticeVal GetValueInBlock(Value *V, BasicBlock *BB, + DenseMap &BlockVals) { + // See if we already have a value for this block. + LVILatticeVal &BBLV = BlockVals[BB]; + + // If we've already computed this block's value, return it. + if (!BBLV.isUndefined()) + return BBLV; + + // Otherwise, this is the first time we're seeing this block. Reset the + // lattice value to overdefined, so that cycles will terminate and be + // conservatively correct. + BBLV.markOverdefined(); + + LVILatticeVal Result; // Start Undefined. + + // If V is live in to BB, see if our predecessors know anything about it. + Instruction *BBI = dyn_cast(V); + if (BBI == 0 || BBI->getParent() != BB) { + unsigned NumPreds = 0; + + // Loop over all of our predecessors, merging what we know from them into + // result. + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { + Result.mergeIn(GetValueOnEdge(V, *PI, BB, BlockVals)); + + // If we hit overdefined, exit early. The BlockVals entry is already set + // to overdefined. + if (Result.isOverdefined()) + return Result; + ++NumPreds; + } + + // If this is the entry block, we must be asking about an argument. The + // value is overdefined. + if (NumPreds == 0 && BB == &BB->getParent()->front()) { + assert(isa(V) && "Unknown live-in to the entry block"); + Result.markOverdefined(); + return Result; + } + + // Return the merged value, which is more precise than 'overdefined'. + assert(!Result.isOverdefined()); + return BlockVals[BB] = Result; + } + + // If this value is defined by an instruction in this block, we have to + // process it here somehow or return overdefined. + if (PHINode *PN = dyn_cast(BBI)) { + (void)PN; + // TODO: PHI Translation in preds. + } else { + + } + + Result.markOverdefined(); + return BlockVals[BB] = Result; +} + + +Constant *LazyValueInfo::getConstant(Value *V, BasicBlock *BB) { + // If already a constant, return it. + if (Constant *VC = dyn_cast(V)) + return VC; + + DenseMap BlockValues; + + errs() << "Getting value " << *V << " at end of block '" + << BB->getName() << "'\n"; + LVILatticeVal Result = GetValueInBlock(V, BB, BlockValues); + + errs() << " Result = " << Result << "\n"; + + if (Result.isConstant()) + return Result.getConstant(); + return 0; +} /// isEqual - Determine whether the specified value is known to be equal or /// not-equal to the specified constant at the end of the specified block. @@ -135,12 +287,4 @@ return Unknown; } -Constant *LazyValueInfo::getConstant(Value *V, BasicBlock *BB) { - // If already a constant, return it. - if (Constant *VC = dyn_cast(V)) - return VC; - - // Not a very good implementation. - return 0; -} From bob.wilson at apple.com Wed Nov 11 17:05:45 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 11 Nov 2009 23:05:45 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h Message-ID: <200911112305.nABN5jd1010544@zion.cs.uiuc.edu> Author: bwilson Date: Wed Nov 11 17:05:45 2009 New Revision: 86892 URL: http://llvm.org/viewvc/llvm-project?rev=86892&view=rev Log: Fix pr5406: When passing an aggregate in integer registers, the data cannot be split up into integer types smaller than the target registers. Most of the data is put into an array of i32 or i64 values, and that part is OK. But, if the size is not a multiple of 32 or 64, there may be some leftover bytes to be passed separately. Change to pass those leftover bytes in a single integer. The x86_64 target already does this in target-specific code. This also fixes radars 7226380 and 7226213. Modified: llvm-gcc-4.2/trunk/gcc/llvm-abi.h Modified: llvm-gcc-4.2/trunk/gcc/llvm-abi.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-abi.h?rev=86892&r1=86891&r2=86892&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Wed Nov 11 17:05:45 2009 @@ -629,19 +629,18 @@ Elts.push_back(ATy); } - if (Size >= 4) { + // Put any left over bytes into one last register. This target-independent + // code does not know the size of the argument registers, so use the + // smallest size that will work. + if (Size > 4) { + Elts.push_back(Type::getInt64Ty(getGlobalContext())); + } else if (Size > 2) { Elts.push_back(Type::getInt32Ty(getGlobalContext())); - Size -= 4; - } - if (Size >= 2) { + } else if (Size > 1) { Elts.push_back(Type::getInt16Ty(getGlobalContext())); - Size -= 2; - } - if (Size >= 1) { + } else { Elts.push_back(Type::getInt8Ty(getGlobalContext())); - Size -= 1; } - assert(Size == 0 && "Didn't cover value?"); const StructType *STy = StructType::get(getGlobalContext(), Elts, false); unsigned i = 0; @@ -1073,19 +1072,18 @@ Elts.push_back(ATy); } - if (Size >= 4) { + // Put any left over bytes into one last register. This target-independent + // code does not know the size of the argument registers, so use the + // smallest size that will work. + if (Size > 4) { + Elts.push_back(Type::getInt64Ty(getGlobalContext())); + } else if (Size > 2) { Elts.push_back(Type::getInt32Ty(getGlobalContext())); - Size -= 4; - } - if (Size >= 2) { + } else if (Size > 1) { Elts.push_back(Type::getInt16Ty(getGlobalContext())); - Size -= 2; - } - if (Size >= 1) { + } else { Elts.push_back(Type::getInt8Ty(getGlobalContext())); - Size -= 1; } - assert(Size == 0 && "Didn't cover value?"); const StructType *STy = StructType::get(getGlobalContext(), Elts, false); unsigned i = 0; From bruno.cardoso at gmail.com Wed Nov 11 17:09:33 2009 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Wed, 11 Nov 2009 23:09:33 -0000 Subject: [llvm-commits] [llvm] r86895 - /llvm/trunk/lib/Target/Mips/MipsInstrFPU.td Message-ID: <200911112309.nABN9XLg010712@zion.cs.uiuc.edu> Author: bruno Date: Wed Nov 11 17:09:33 2009 New Revision: 86895 URL: http://llvm.org/viewvc/llvm-project?rev=86895&view=rev Log: A real solution for the first part of PR5445 Modified: llvm/trunk/lib/Target/Mips/MipsInstrFPU.td Modified: llvm/trunk/lib/Target/Mips/MipsInstrFPU.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrFPU.td?rev=86895&r1=86894&r2=86895&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrFPU.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrFPU.td Wed Nov 11 17:09:33 2009 @@ -281,10 +281,15 @@ // Floating Point Patterns //===----------------------------------------------------------------------===// def fpimm0 : PatLeaf<(fpimm), [{ - return N->isExactlyValue(+0.0) || N->isExactlyValue(-0.0); + return N->isExactlyValue(+0.0); +}]>; + +def fpimm0neg : PatLeaf<(fpimm), [{ + return N->isExactlyValue(-0.0); }]>; def : Pat<(f32 fpimm0), (MTC1 ZERO)>; +def : Pat<(f32 fpimm0neg), (FNEG_S32 (MTC1 ZERO))>; def : Pat<(f32 (sint_to_fp CPURegs:$src)), (CVTS_W32 (MTC1 CPURegs:$src))>; def : Pat<(f64 (sint_to_fp CPURegs:$src)), (CVTD_W32 (MTC1 CPURegs:$src))>; From isanbard at gmail.com Wed Nov 11 17:17:02 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 11 Nov 2009 23:17:02 -0000 Subject: [llvm-commits] [llvm] r86897 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Message-ID: <200911112317.nABNH2X5011048@zion.cs.uiuc.edu> Author: void Date: Wed Nov 11 17:17:02 2009 New Revision: 86897 URL: http://llvm.org/viewvc/llvm-project?rev=86897&view=rev Log: Don't mark a call as potentially throwing if the function it's calling has the "nounwind" attribute. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp?rev=86897&r1=86896&r2=86897&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Wed Nov 11 17:17:02 2009 @@ -490,7 +490,27 @@ for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); MI != E; ++MI) { if (!MI->isLabel()) { - SawPotentiallyThrowing |= MI->getDesc().isCall(); + if (MI->getDesc().isCall()) { + // Don't mark a call as potentially throwing if the function it's + // calling is marked "nounwind". + bool DoesNotThrow = false; + for (unsigned OI = 0, OE = MI->getNumOperands(); OI != OE; ++OI) { + const MachineOperand &MO = MI->getOperand(OI); + + if (MO.isGlobal()) { + if (Function *F = dyn_cast(MO.getGlobal())) { + if (F->doesNotThrow()) { + DoesNotThrow = true; + break; + } + } + } + } + + if (!DoesNotThrow) + SawPotentiallyThrowing = true; + } + continue; } From sabre at nondot.org Wed Nov 11 18:36:10 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 11 Nov 2009 18:36:10 -0600 Subject: [llvm-commits] CVS: llvm-www/Users.html Message-ID: <200911120036.nAC0aAjQ013856@zion.cs.uiuc.edu> Changes in directory llvm-www: Users.html updated: 1.71 -> 1.72 --- Log message: fix broken link --- Diffs of the changes: (+2 -2) Users.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-www/Users.html diff -u llvm-www/Users.html:1.71 llvm-www/Users.html:1.72 --- llvm-www/Users.html:1.71 Fri Oct 30 10:43:56 2009 +++ llvm-www/Users.html Wed Nov 11 18:35:12 2009 @@ -196,7 +196,7 @@ XMOS Technology - Backend port for their + Backend port for their architecture, also working on multicore codegen support. @@ -583,6 +583,6 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!">
    LLVM Development List
    - Last modified: $Date: 2009/10/30 15:43:56 $ + Last modified: $Date: 2009/11/12 00:35:12 $ From gohman at apple.com Wed Nov 11 18:39:10 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 12 Nov 2009 00:39:10 -0000 Subject: [llvm-commits] [llvm] r86909 - in /llvm/trunk: lib/CodeGen/BranchFolding.cpp test/CodeGen/X86/tail-opts.ll Message-ID: <200911120039.nAC0dA6V013985@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 11 18:39:10 2009 New Revision: 86909 URL: http://llvm.org/viewvc/llvm-project?rev=86909&view=rev Log: Tail merge at any size when there are two potentials blocks and one can be made to fall through into the other. Modified: llvm/trunk/lib/CodeGen/BranchFold