fourthTier: FTL should be able to generate LLVM IR that uses an intrinsic for OSR...
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jul 2013 04:05:18 +0000 (04:05 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jul 2013 04:05:18 +0000 (04:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=118948

Source/JavaScriptCore:

Reviewed by Sam Weinig.

- Add the ability to generate LLVM IR but then not use it, via --llvmAlwaysFails=true.
  This allows doing "what if" experiments with IR generation, even if the generated IR
  can't yet execute.

- Add an OSR exit path that just calls an intrinsic that combines the branch and the
  off-ramp.

* JavaScriptCore.xcodeproj/project.pbxproj:
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* ftl/FTLFail.cpp: Added.
(FTL):
(JSC::FTL::fail):
* ftl/FTLFail.h: Added.
(FTL):
* ftl/FTLIntrinsicRepository.h:
(FTL):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::appendOSRExit):
(JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
* runtime/Options.h:
(JSC):

Tools:

Reviewed by Sam Weinig.

- Make ReducedFTL capable of dealing with code that uses the fake OSR exit intrinsic,
  by exporting it as a function.

- Make combineModules.rb idempotent. Sometimes it's convenient to run a file through
  it even if you know that you've already done so. See processIRDump.sh.

- Add a script, processIRDump.sh, that takes the output of --dumpLLVMIR=true and
  runs it through ReducedFTL automatically. You typically want to say something like:

  jsc --dumpLLVMIR=true <program(s)> > jsc-output.txt
  ./processIRDump.sh --timing < jsc-output.txt

* ReducedFTL/ReducedFTL.c:
(webkit_osr_exit):
* ReducedFTL/combineModules.rb:
* ReducedFTL/processIRDump.sh: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153289 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/dfg/DFGPlan.cpp
Source/JavaScriptCore/ftl/FTLFail.cpp [new file with mode: 0644]
Source/JavaScriptCore/ftl/FTLFail.h [new file with mode: 0644]
Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h
Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
Source/JavaScriptCore/runtime/Options.h
Tools/ChangeLog
Tools/ReducedFTL/ReducedFTL.c
Tools/ReducedFTL/combineModules.rb
Tools/ReducedFTL/processIRDump.sh [new file with mode: 0755]

index 40248d9..d970944 100644 (file)
@@ -1,3 +1,33 @@
+2013-07-20  Filip Pizlo  <fpizlo@apple.com>
+
+        fourthTier: FTL should be able to generate LLVM IR that uses an intrinsic for OSR exit
+        https://bugs.webkit.org/show_bug.cgi?id=118948
+
+        Reviewed by Sam Weinig.
+        
+        - Add the ability to generate LLVM IR but then not use it, via --llvmAlwaysFails=true.
+          This allows doing "what if" experiments with IR generation, even if the generated IR
+          can't yet execute.
+        
+        - Add an OSR exit path that just calls an intrinsic that combines the branch and the
+          off-ramp.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * ftl/FTLFail.cpp: Added.
+        (FTL):
+        (JSC::FTL::fail):
+        * ftl/FTLFail.h: Added.
+        (FTL):
+        * ftl/FTLIntrinsicRepository.h:
+        (FTL):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
+        (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
+        * runtime/Options.h:
+        (JSC):
+
 2013-07-19  Filip Pizlo  <fpizlo@apple.com>
 
         fourthTier: StringObjectUse uses structures, and CSE should know that
index c4b991a..930a102 100644 (file)
                034768DFFF38A50411DB9C8B /* Products */ = {
                        isa = PBXGroup;
                        children = (
+                               932F5BD90822A1C700736975 /* JavaScriptCore.framework */,
                                932F5BE10822A1C700736975 /* jsc */,
                                0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */,
-                               932F5BD90822A1C700736975 /* JavaScriptCore.framework */,
                                141211200A48793C00480255 /* minidom */,
                                14BD59BF0A3E8F9000BAF59C /* testapi */,
                                6511230514046A4C002B101D /* testRegExp */,
index 4c8f8b7..3a2c8f7 100644 (file)
@@ -54,6 +54,7 @@
 #include "DFGVirtualRegisterAllocationPhase.h"
 #include "FTLCapabilities.h"
 #include "FTLCompile.h"
+#include "FTLFail.h"
 #include "FTLLink.h"
 #include "FTLLowerDFGToLLVM.h"
 #include "FTLState.h"
@@ -223,6 +224,11 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
         if (Options::reportCompileTimes())
             beforeFTL = currentTimeMS();
         
+        if (Options::llvmAlwaysFails()) {
+            FTL::fail(state);
+            return FTLPath;
+        }
+        
         FTL::compile(state);
         FTL::link(state);
         return FTLPath;
diff --git a/Source/JavaScriptCore/ftl/FTLFail.cpp b/Source/JavaScriptCore/ftl/FTLFail.cpp
new file mode 100644 (file)
index 0000000..9dd7c0a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "FTLFail.h"
+
+#if ENABLE(FTL_JIT)
+
+#include "DFGFailedFinalizer.h"
+#include "FTLJITCode.h"
+#include <wtf/LLVMHeaders.h>
+
+namespace JSC { namespace FTL {
+
+using namespace DFG;
+
+void fail(State& state)
+{
+    state.graph.m_plan.finalizer = adoptPtr(new FailedFinalizer(state.graph.m_plan));
+    
+    LLVMDisposeModule(state.module);
+}
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
diff --git a/Source/JavaScriptCore/ftl/FTLFail.h b/Source/JavaScriptCore/ftl/FTLFail.h
new file mode 100644 (file)
index 0000000..1d6432c
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef FTLFail_h
+#define FTLFail_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(FTL_JIT)
+
+#include "FTLState.h"
+
+namespace JSC { namespace FTL {
+
+void fail(State&);
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
+#endif // FTLFail_h
+
index 832e139..cc99746 100644 (file)
@@ -41,7 +41,8 @@ namespace JSC { namespace FTL {
     macro(doubleAbs, "llvm.fabs.f64", functionType(doubleType, doubleType)) \
     macro(mulWithOverflow32, "llvm.smul.with.overflow.i32", functionType(structType(m_context, int32, boolean), int32, int32)) \
     macro(subWithOverflow32, "llvm.ssub.with.overflow.i32", functionType(structType(m_context, int32, boolean), int32, int32)) \
-    macro(trap, "llvm.trap", functionType(voidType))
+    macro(trap, "llvm.trap", functionType(voidType)) \
+    macro(osrExit, "webkit_osr_exit", functionType(voidType, boolean, int32, Variadic))
 
 #define FOR_EACH_FUNCTION_TYPE(macro) \
     macro(I_DFGOperation_EJss, functionType(intPtr, intPtr, intPtr)) \
index 880915d..56113c5 100644 (file)
@@ -2488,35 +2488,49 @@ private:
         OSRExit& exit = m_ftlState.jitCode->osrExit.last();
         OSRExitCompilationInfo& info = m_ftlState.osrExit.last();
 
-        LBasicBlock failCase = FTL_NEW_BLOCK(m_out, ("OSR exit failCase"));
-        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("OSR exit continuation"));
+        LBasicBlock lastNext = 0;
+        LBasicBlock continuation = 0;
         
-        m_out.branch(failCondition, failCase, continuation);
+        if (!Options::useLLVMOSRExitIntrinsic()) {
+            LBasicBlock failCase = FTL_NEW_BLOCK(m_out, ("OSR exit failCase"));
+            continuation = FTL_NEW_BLOCK(m_out, ("OSR exit continuation"));
+            
+            m_out.branch(failCondition, failCase, continuation);
+
+            m_out.appendTo(m_prologue);
+            info.m_thunkAddress = buildAlloca(m_out.m_builder, m_out.intPtr);
         
-        m_out.appendTo(m_prologue);
-        info.m_thunkAddress = buildAlloca(m_out.m_builder, m_out.intPtr);
+            lastNext = m_out.appendTo(failCase, continuation);
+        }
         
-        LBasicBlock lastNext = m_out.appendTo(failCase, continuation);
-
         if (Options::ftlOSRExitOmitsMarshalling()) {
             m_out.call(
                 m_out.intToPtr(
                     m_out.get(info.m_thunkAddress),
                     pointerType(functionType(m_out.voidType))));
         } else
-            emitOSRExitCall(exit, info, lowValue, direction, recovery);
-        m_out.unreachable();
+            emitOSRExitCall(failCondition, index, exit, info, lowValue, direction, recovery);
         
-        m_out.appendTo(continuation, lastNext);
+        if (!Options::useLLVMOSRExitIntrinsic()) {
+            m_out.unreachable();
+            
+            m_out.appendTo(continuation, lastNext);
         
-        m_exitThunkGenerator.emitThunk(index);
+            m_exitThunkGenerator.emitThunk(index);
+        }
     }
     
     void emitOSRExitCall(
-        OSRExit& exit, OSRExitCompilationInfo& info, FormattedValue lowValue,
-        SpeculationDirection direction, FormattedValue recovery)
+        LValue failCondition, unsigned index, OSRExit& exit, OSRExitCompilationInfo& info,
+        FormattedValue lowValue, SpeculationDirection direction, FormattedValue recovery)
     {
         ExitArgumentList arguments;
+        
+        if (Options::useLLVMOSRExitIntrinsic()) {
+            arguments.append(failCondition);
+            arguments.append(m_out.constInt32(index));
+        }
+        
         arguments.append(m_callFrame);
         if (!!lowValue)
             arguments.append(lowValue.value());
@@ -2560,6 +2574,11 @@ private:
         for (unsigned i = 0; i < arguments.size(); ++i)
             argumentTypes.append(typeOf(arguments[i]));
         
+        if (Options::useLLVMOSRExitIntrinsic()) {
+            m_out.call(m_out.osrExitIntrinsic(), arguments);
+            return;
+        }
+        
         m_out.call(
             m_out.intToPtr(
                 m_out.get(info.m_thunkAddress),
index 931b99a..a34da62 100644 (file)
@@ -122,7 +122,9 @@ typedef OptionRange optionRange;
     v(bool, useLLVMSmallCodeModel, false) \
     v(bool, ftlTrapsOnOSRExit, false) \
     v(bool, ftlOSRExitOmitsMarshalling, false) \
+    v(bool, useLLVMOSRExitIntrinsic, false) \
     v(bool, dumpLLVMIR, false) \
+    v(bool, llvmAlwaysFails, false) \
     v(unsigned, llvmBackendOptimizationLevel, 2) \
     v(unsigned, llvmOptimizationLevel, 2) \
     v(unsigned, llvmSizeLevel, 0) \
index 2a2fb17..072b2c7 100644 (file)
@@ -1,5 +1,29 @@
 2013-07-20  Filip Pizlo  <fpizlo@apple.com>
 
+        fourthTier: FTL should be able to generate LLVM IR that uses an intrinsic for OSR exit
+        https://bugs.webkit.org/show_bug.cgi?id=118948
+
+        Reviewed by Sam Weinig.
+        
+        - Make ReducedFTL capable of dealing with code that uses the fake OSR exit intrinsic,
+          by exporting it as a function.
+        
+        - Make combineModules.rb idempotent. Sometimes it's convenient to run a file through
+          it even if you know that you've already done so. See processIRDump.sh.
+        
+        - Add a script, processIRDump.sh, that takes the output of --dumpLLVMIR=true and
+          runs it through ReducedFTL automatically. You typically want to say something like:
+          
+          jsc --dumpLLVMIR=true <program(s)> > jsc-output.txt
+          ./processIRDump.sh --timing < jsc-output.txt
+
+        * ReducedFTL/ReducedFTL.c:
+        (webkit_osr_exit):
+        * ReducedFTL/combineModules.rb:
+        * ReducedFTL/processIRDump.sh: Added.
+
+2013-07-20  Filip Pizlo  <fpizlo@apple.com>
+
         fourthTier: We should use the no-asserts build of LLVM if that's what the user configured
         https://bugs.webkit.org/show_bug.cgi?id=118947
 
index 9a05c21..1351fb2 100644 (file)
@@ -146,6 +146,11 @@ static const char *symbolLookupCallback(
     }
 }
 
+void webkit_osr_exit()
+{
+    abort();
+}
+
 int main(int c, char **v)
 {
     LLVMContextRef *contexts;
index 105d6fb..c3f2efe 100755 (executable)
@@ -78,9 +78,16 @@ $count = 0
 
 loop {
     line = $stdin.readline
+    if line =~ /^; NOTE: THIS IS A COMBINED MODULE/
+        puts line
+        puts $stdin.read
+        exit 0
+    end
     break if line =~ /^define/
 }
 
+puts "; NOTE: THIS IS A COMBINED MODULE"
+
 # Loop over all definitions.
 shouldContinue = true
 while shouldContinue
diff --git a/Tools/ReducedFTL/processIRDump.sh b/Tools/ReducedFTL/processIRDump.sh
new file mode 100755 (executable)
index 0000000..b1de1df
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+set -e
+set -x
+
+if test "x${LLVM_PATH}" == "x"
+then
+    path=
+else
+    path="${LLVM_PATH}/bin/"
+fi
+
+./combineModules.rb > temp.ll
+${path}llvm-as temp.ll
+./ReducedFTL temp.bc "$@"