summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGCommon.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGCommon.h')
-rw-r--r--Source/JavaScriptCore/dfg/DFGCommon.h193
1 files changed, 151 insertions, 42 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGCommon.h b/Source/JavaScriptCore/dfg/DFGCommon.h
index 14c47cefc..7aef749b0 100644
--- a/Source/JavaScriptCore/dfg/DFGCommon.h
+++ b/Source/JavaScriptCore/dfg/DFGCommon.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 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
@@ -35,7 +35,7 @@
#include "VirtualRegister.h"
/* DFG_ENABLE() - turn on a specific features in the DFG JIT */
-#define DFG_ENABLE(DFG_FEATURE) (defined DFG_ENABLE_##DFG_FEATURE && DFG_ENABLE_##DFG_FEATURE)
+#define DFG_ENABLE(DFG_FEATURE) (defined DFG_ENABLE_##DFG_FEATURE && DFG_ENABLE_##DFG_FEATURE)
// Emit various logging information for debugging, including dumping the dataflow graphs.
#define DFG_ENABLE_DEBUG_VERBOSE 0
@@ -50,14 +50,6 @@
#else
#define DFG_ENABLE_JIT_ASSERT 0
#endif
-// Enable validation of the graph.
-#if !ASSERT_DISABLED
-#define DFG_ENABLE_VALIDATION 1
-#else
-#define DFG_ENABLE_VALIDATION 0
-#endif
-// Enable validation on completion of each phase.
-#define DFG_ENABLE_PER_PHASE_VALIDATION 0
// Consistency check contents compiler data structures.
#define DFG_ENABLE_CONSISTENCY_CHECK 0
// Emit a breakpoint into the head of every generated function, to aid debugging in GDB.
@@ -70,8 +62,6 @@
#define DFG_ENABLE_XOR_DEBUG_AID 0
// Emit a breakpoint into the speculation failure code.
#define DFG_ENABLE_JIT_BREAK_ON_SPECULATION_FAILURE 0
-// Log every speculation failure.
-#define DFG_ENABLE_VERBOSE_SPECULATION_FAILURE 0
// Disable the DFG JIT without having to touch Platform.h
#define DFG_DEBUG_LOCAL_DISBALE 0
// Enable OSR entry from baseline JIT.
@@ -83,49 +73,66 @@
namespace JSC { namespace DFG {
-// Type for a reference to another node in the graph.
-typedef uint32_t NodeIndex;
-static const NodeIndex NoNode = UINT_MAX;
+struct Node;
typedef uint32_t BlockIndex;
static const BlockIndex NoBlock = UINT_MAX;
-struct NodeIndexTraits {
- static NodeIndex defaultValue() { return NoNode; }
- static void dump(NodeIndex value, PrintStream& out)
- {
- if (value == NoNode)
- out.printf("-");
- else
- out.printf("@%u", value);
- }
+struct NodePointerTraits {
+ static Node* defaultValue() { return 0; }
+ static void dump(Node* value, PrintStream& out);
};
-enum UseKind {
- UntypedUse,
- DoubleUse,
- LastUseKind // Must always be the last entry in the enum, as it is used to denote the number of enum elements.
+// Use RefChildren if the child ref counts haven't already been adjusted using
+// other means and either of the following is true:
+// - The node you're creating is MustGenerate.
+// - The place where you're inserting a reference to the node you're creating
+// will not also do RefChildren.
+enum RefChildrenMode {
+ RefChildren,
+ DontRefChildren
};
-inline const char* useKindToString(UseKind useKind)
+// Use RefNode if you know that the node will be used from another node, and you
+// will not already be ref'ing the node to account for that use.
+enum RefNodeMode {
+ RefNode,
+ DontRefNode
+};
+
+inline bool verboseCompilationEnabled()
{
- switch (useKind) {
- case UntypedUse:
- return "";
- case DoubleUse:
- return "d";
- default:
- ASSERT_NOT_REACHED();
- return 0;
- }
+#if DFG_ENABLE(DEBUG_VERBOSE)
+ return true;
+#else
+ return Options::verboseCompilation() || Options::dumpGraphAtEachPhase();
+#endif
}
-inline bool isX86()
+inline bool logCompilationChanges()
{
-#if CPU(X86_64) || CPU(X86)
+#if DFG_ENABLE(DEBUG_VERBOSE)
return true;
#else
- return false;
+ return verboseCompilationEnabled() || Options::logCompilationChanges();
+#endif
+}
+
+inline bool shouldDumpGraphAtEachPhase()
+{
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ return true;
+#else
+ return Options::dumpGraphAtEachPhase();
+#endif
+}
+
+inline bool validationEnabled()
+{
+#if !ASSERT_DISABLED
+ return true;
+#else
+ return Options::validateGraph() || Options::validateGraphAtEachPhase();
#endif
}
@@ -135,15 +142,117 @@ enum NoResultTag { NoResult };
enum OptimizationFixpointState { BeforeFixpoint, FixpointNotConverged, FixpointConverged };
+// Describes the form you can expect the entire graph to be in.
+enum GraphForm {
+ // LoadStore form means that basic blocks may freely use GetLocal, SetLocal,
+ // GetLocalUnlinked, and Flush for accessing local variables and indicating
+ // where their live ranges ought to be. Data flow between local accesses is
+ // implicit. Liveness is only explicit at block heads (variablesAtHead).
+ // This is only used by the DFG simplifier and is only preserved by same.
+ //
+ // For example, LoadStore form gives no easy way to determine which SetLocal's
+ // flow into a GetLocal. As well, LoadStore form implies no restrictions on
+ // redundancy: you can freely emit multiple GetLocals, or multiple SetLocals
+ // (or any combination thereof) to the same local in the same block. LoadStore
+ // form does not require basic blocks to declare how they affect or use locals,
+ // other than implicitly by using the local ops and by preserving
+ // variablesAtHead. Finally, LoadStore allows flexibility in how liveness of
+ // locals is extended; for example you can replace a GetLocal with a Phantom
+ // and so long as the Phantom retains the GetLocal's children (i.e. the Phi
+ // most likely) then it implies that the local is still live but that it need
+ // not be stored to the stack necessarily. This implies that Phantom can
+ // reference nodes that have no result, as long as those nodes are valid
+ // GetLocal children (i.e. Phi, SetLocal, SetArgument).
+ //
+ // LoadStore form also implies that Phis need not have children. By default,
+ // they end up having no children if you enter LoadStore using the canonical
+ // way (call Graph::dethread).
+ //
+ // LoadStore form is suitable for CFG transformations, as well as strength
+ // reduction, folding, and CSE.
+ LoadStore,
+
+ // ThreadedCPS form means that basic blocks list up-front which locals they
+ // expect to be live at the head, and which locals they make available at the
+ // tail. ThreadedCPS form also implies that:
+ //
+ // - GetLocals and SetLocals to uncaptured variables are not redundant within
+ // a basic block.
+ //
+ // - All GetLocals and Flushes are linked directly to the last access point
+ // of the variable, which must not be another GetLocal if the variable is
+ // uncaptured.
+ //
+ // - Phantom(Phi) is not legal, but PhantomLocal is.
+ //
+ // ThreadedCPS form is suitable for data flow analysis (CFA, prediction
+ // propagation), register allocation, and code generation.
+ ThreadedCPS
+};
+
+// Describes the state of the UnionFind structure of VariableAccessData's.
+enum UnificationState {
+ // BasicBlock-local accesses to variables are appropriately unified with each other.
+ LocallyUnified,
+
+ // Unification has been performed globally.
+ GloballyUnified
+};
+
+// Describes how reference counts in the graph behave.
+enum RefCountState {
+ // Everything has refCount() == 1.
+ EverythingIsLive,
+
+ // Set after DCE has run.
+ ExactRefCount
+};
+
+enum OperandSpeculationMode { AutomaticOperandSpeculation, ManualOperandSpeculation };
+
+enum SpeculationDirection { ForwardSpeculation, BackwardSpeculation };
+
+enum ProofStatus { NeedsCheck, IsProved };
+
+inline bool isProved(ProofStatus proofStatus)
+{
+ ASSERT(proofStatus == IsProved || proofStatus == NeedsCheck);
+ return proofStatus == IsProved;
+}
+
+inline ProofStatus proofStatusForIsProved(bool isProved)
+{
+ return isProved ? IsProved : NeedsCheck;
+}
+
+template<typename T, typename U>
+bool checkAndSet(T& left, U right)
+{
+ if (left == right)
+ return false;
+ left = right;
+ return true;
+}
+
} } // namespace JSC::DFG
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::DFG::OptimizationFixpointState);
+void printInternal(PrintStream&, JSC::DFG::GraphForm);
+void printInternal(PrintStream&, JSC::DFG::UnificationState);
+void printInternal(PrintStream&, JSC::DFG::RefCountState);
+void printInternal(PrintStream&, JSC::DFG::ProofStatus);
+
+} // namespace WTF
+
#endif // ENABLE(DFG_JIT)
namespace JSC { namespace DFG {
// Put things here that must be defined even if ENABLE(DFG_JIT) is false.
-enum CapabilityLevel { CannotCompile, ShouldProfile, CanCompile, CapabilityLevelNotSet };
+enum CapabilityLevel { CannotCompile, MayInline, CanCompile, CapabilityLevelNotSet };
// Unconditionally disable DFG disassembly support if the DFG is not compiled in.
inline bool shouldShowDisassembly()