Modify nanojit::live, expose ReverseLister, add some options to VerboseWriter (r=edwsmith,graydon,bug=538000)
authorSteven Johnson <stejohns@adobe.com>
Thu, 07 Jan 2010 16:41:42 -0800
changeset 37668 6eeab16a494eefcea2d6a159b23e29b5f907f0f0
parent 37667 938600f64c100d41f2de29f63ebfb7be57a8108a
child 37669 bb06ca4ba19da8b8d718a0fbe9bc9e81a3b305e6
push id11426
push userrsayre@mozilla.com
push dateSun, 31 Jan 2010 16:36:36 +0000
treeherderautoland@3048d03980e7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersedwsmith, graydon
bugs538000
milestone1.9.3a1pre
Modify nanojit::live, expose ReverseLister, add some options to VerboseWriter (r=edwsmith,graydon,bug=538000)
js/src/nanojit/Assembler.h
js/src/nanojit/LIR.cpp
js/src/nanojit/LIR.h
--- a/js/src/nanojit/Assembler.h
+++ b/js/src/nanojit/Assembler.h
@@ -222,18 +222,16 @@ namespace nanojit
         LabelStateMap(Allocator& alloc) : alloc(alloc), labels(alloc)
         {}
 
         void clear() { labels.clear(); }
         void add(LIns *label, NIns *addr, RegAlloc &regs);
         LabelState *get(LIns *);
     };
 
-    typedef SeqBuilder<char*> StringList;
-
     /** map tracking the register allocation state at each bailout point
      *  (represented by SideExit*) in a trace fragment. */
     typedef HashMap<SideExit*, RegAlloc*> RegAllocMap;
 
     /**
      * Information about the activation record for the method is built up
      * as we generate machine code.  As part of the prologue, we issue
      * a stack adjustment instruction and then later patch the adjustment
--- a/js/src/nanojit/LIR.cpp
+++ b/js/src/nanojit/LIR.cpp
@@ -70,60 +70,36 @@ namespace nanojit
 #undef OPDEF
         NULL
     };
 
     #endif /* NANOJIT_VEBROSE */
 
     // implementation
 #ifdef NJ_VERBOSE
-    /* A listing filter for LIR, going through backwards.  It merely
-       passes its input to its output, but notes it down too.  When
-       destructed, prints out what went through.  Is intended to be
-       used to print arbitrary intermediate transformation stages of
-       LIR. */
-    class ReverseLister : public LirFilter
+    void ReverseLister::finish()
     {
-        Allocator&   _alloc;
-        LirNameMap*  _names;
-        const char*  _title;
-        StringList   _strs;
-        LogControl*  _logc;
-    public:
-        ReverseLister(LirFilter* in, Allocator& alloc,
-                      LirNameMap* names, LogControl* logc, const char* title)
-            : LirFilter(in)
-            , _alloc(alloc)
-            , _names(names)
-            , _title(title)
-            , _strs(alloc)
-            , _logc(logc)
-        { }
+        _logc->printf("\n");
+        _logc->printf("=== BEGIN %s ===\n", _title);
+        int j = 0;
+        for (Seq<char*>* p = _strs.get(); p != NULL; p = p->tail)
+            _logc->printf("  %02d: %s\n", j++, p->head);
+        _logc->printf("=== END %s ===\n", _title);
+        _logc->printf("\n");
+    }
 
-        void finish()
-        {
-            _logc->printf("\n");
-            _logc->printf("=== BEGIN %s ===\n", _title);
-            int j = 0;
-            for (Seq<char*>* p = _strs.get(); p != NULL; p = p->tail)
-                _logc->printf("  %02d: %s\n", j++, p->head);
-            _logc->printf("=== END %s ===\n", _title);
-            _logc->printf("\n");
-        }
-
-        LInsp read()
-        {
-            LInsp i = in->read();
-            const char* str = _names->formatIns(i);
-            char* cpy = new (_alloc) char[strlen(str)+1];
-            VMPI_strcpy(cpy, str);
-            _strs.insert(cpy);
-            return i;
-        }
-    };
+    LInsp ReverseLister::read()
+    {
+        LInsp i = in->read();
+        const char* str = _names->formatIns(i);
+        char* cpy = new (_alloc) char[strlen(str)+1];
+        VMPI_strcpy(cpy, str);
+        _strs.insert(cpy);
+        return i;
+    }
 #endif
 
 #ifdef NJ_PROFILE
     // @todo fixup move to nanojit.h
     #undef counter_value
     #define counter_value(x)        x
 #endif /* NJ_PROFILE */
 
@@ -1464,28 +1440,26 @@ namespace nanojit
 
     /*
      * traverse the LIR buffer and discover which instructions are live
      * by starting from instructions with side effects (stores, calls, branches)
      * and marking instructions used by them.  Works bottom-up, in one pass.
      * if showLiveRefs == true, also print the set of live expressions next to
      * each instruction
      */
-    void live(Allocator& alloc, Fragment *frag, LogControl *logc)
+    void live(LirFilter* in, Allocator& alloc, Fragment *frag, LogControl *logc)
     {
         // traverse backwards to find live exprs and a few other stats.
 
         LiveTable live(alloc);
         uint32_t exits = 0;
-        LirReader br(frag->lastIns);
-        StackFilter sf(&br, alloc, frag->lirbuf, frag->lirbuf->sp, frag->lirbuf->rp);
         int total = 0;
         if (frag->lirbuf->state)
-            live.add(frag->lirbuf->state, sf.pos());
-        for (LInsp ins = sf.read(); !ins->isop(LIR_start); ins = sf.read())
+            live.add(frag->lirbuf->state, in->pos());
+        for (LInsp ins = in->read(); !ins->isop(LIR_start); ins = in->read())
         {
             total++;
 
             // first handle side-effect instructions
             if (ins->isStmt())
             {
                 live.add(ins, 0);
                 if (ins->isGuard())
@@ -2165,17 +2139,19 @@ namespace nanojit
             logc->printf("===\n");
         })
         /* END decorative preamble */
 
         verbose_only( if (liveVerb) {
             logc->printf("\n");
             logc->printf("=== Results of liveness analysis:\n");
             logc->printf("===\n");
-            live(alloc, frag, logc);
+            LirReader br(frag->lastIns);
+            StackFilter sf(&br, alloc, frag->lirbuf, frag->lirbuf->sp, frag->lirbuf->rp);
+            live(&sf, alloc, frag, logc);
         })
 
         /* Set up the generic text output cache for the assembler */
         verbose_only( StringList asmOutput(alloc); )
         verbose_only( assm->_outputCache = &asmOutput; )
 
         assm->beginAssembly(frag);
         if (assm->error())
--- a/js/src/nanojit/LIR.h
+++ b/js/src/nanojit/LIR.h
@@ -581,16 +581,17 @@ namespace nanojit
         #else
             return (void*)imm32();
         #endif
         }
     };
 
     typedef LIns* LInsp;
     typedef SeqBuilder<LIns*> InsList;
+    typedef SeqBuilder<char*> StringList;
 
 
     // 0-operand form.  Used for LIR_start and LIR_label.
     class LInsOp0
     {
     private:
         friend class LIns;
 
@@ -1158,40 +1159,45 @@ namespace nanojit
     };
 
 
     class VerboseWriter : public LirWriter
     {
         InsList code;
         LirNameMap* names;
         LogControl* logc;
+        const char* const prefix;
+        bool const always_flush;
     public:
         VerboseWriter(Allocator& alloc, LirWriter *out,
-                      LirNameMap* names, LogControl* logc)
-            : LirWriter(out), code(alloc), names(names), logc(logc)
+                      LirNameMap* names, LogControl* logc, const char* prefix = "", bool always_flush = false)
+            : LirWriter(out), code(alloc), names(names), logc(logc), prefix(prefix), always_flush(always_flush)
         {}
 
         LInsp add(LInsp i) {
-            if (i)
+            if (i) {
                 code.add(i);
+                if (always_flush)
+                    flush();
+            }
             return i;
         }
 
         LInsp add_flush(LInsp i) {
             if ((i = add(i)) != 0)
                 flush();
             return i;
         }
 
         void flush()
         {
             if (!code.isEmpty()) {
                 int32_t count = 0;
                 for (Seq<LIns*>* p = code.get(); p != NULL; p = p->tail) {
-                    logc->printf("    %s\n",names->formatIns(p->head));
+                    logc->printf("%s    %s\n",prefix,names->formatIns(p->head));
                     count++;
                 }
                 code.clear();
                 if (count > 1)
                     logc->printf("\n");
             }
         }
 
@@ -1473,17 +1479,17 @@ namespace nanojit
         LInsp pos() {
             return _i;
         }
     };
 
     class Assembler;
 
     void compile(Assembler *assm, Fragment *frag, Allocator& alloc verbose_only(, LabelMap*));
-    verbose_only(void live(Allocator& alloc, Fragment* frag, LogControl*);)
+    verbose_only(void live(LirFilter* in, Allocator& alloc, Fragment* frag, LogControl*);)
 
     class StackFilter: public LirFilter
     {
         LirBuffer *lirbuf;
         LInsp sp;
         LInsp rp;
         BitSet spStk;
         BitSet rpStk;
@@ -1535,10 +1541,40 @@ namespace nanojit
         SanityFilter(LirWriter* out) : LirWriter(out)
         { }
     public:
         LIns* ins1(LOpcode v, LIns* s0);
         LIns* ins2(LOpcode v, LIns* s0, LIns* s1);
         LIns* ins3(LOpcode v, LIns* s0, LIns* s1, LIns* s2);
     };
 #endif
+
+#ifdef NJ_VERBOSE
+    /* A listing filter for LIR, going through backwards.  It merely
+       passes its input to its output, but notes it down too.  When
+       finish() is called, prints out what went through.  Is intended to be
+       used to print arbitrary intermediate transformation stages of
+       LIR. */
+    class ReverseLister : public LirFilter
+    {
+        Allocator&   _alloc;
+        LirNameMap*  _names;
+        const char*  _title;
+        StringList   _strs;
+        LogControl*  _logc;
+    public:
+        ReverseLister(LirFilter* in, Allocator& alloc,
+                      LirNameMap* names, LogControl* logc, const char* title)
+            : LirFilter(in)
+            , _alloc(alloc)
+            , _names(names)
+            , _title(title)
+            , _strs(alloc)
+            , _logc(logc)
+        { }
+
+        void finish();
+        LInsp read();
+    };
+#endif
+
 }
 #endif // __nanojit_LIR__