Skip to content

Commit 6366384

Browse files
committed
Add withprob, use in parse
1 parent 157c540 commit 6366384

File tree

2 files changed

+5
-5
lines changed

2 files changed

+5
-5
lines changed

jsrc/j.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,11 @@ static inline omp_int_t omp_get_num_threads() { return 1;}
286286
#if (defined(__has_builtin) && __has_builtin(__builtin_expect_with_probability)) || (!defined(__clang__) && __GNUC__ >= 9)
287287
#define common(x) __builtin_expect_with_probability(!!(x),1,0.6)
288288
#define uncommon(x) __builtin_expect_with_probability(!!(x),1,0.4)
289+
#define withprob(x,p) __builtin_expect_with_probability(!!(x),1,(p))
289290
#else
290291
#define common(x) likely(x)
291292
#define uncommon(x) unlikely(x)
293+
#define withprob(x,p) x
292294
#endif
293295
#else
294296
#define common(x) likely(x)

jsrc/p.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,6 @@ A jtparsea(J jt, A *queue, I nwds){F1PREFIP;PSTK *stack;A z,*v;
530530
// pt0ecam is settling from pt0 but it will be ready soon
531531

532532
do{
533-
// to make the compiler keep queue in regs, you have to convince it that the path back to this loop is common enough
534-
// to give it priority. likelys at the end of the line 0-2 code are key
535533

536534
if(likely((US)pt0ecam!=0)){ // if there is another valid token...
537535
// Move in the new word and check its type. If it is a name that is not being assigned, resolve its
@@ -678,14 +676,14 @@ endname: ;
678676
A fs1=__atomic_load_n(&stack[1].a,__ATOMIC_ACQUIRE); // in case of line 1 V0 V1 N2, we will need the flags from V1. Could be garbage
679677
pt0ecam&=~(VJTFLGOK1+VJTFLGOK2+VASGSAFE+PTNOTLPAR+NOTFINALEXEC+(7LL<<PMASKSAVEX)); // clear all the flags we will use
680678

681-
if(likely(pmask!=0)){ // If all 0, nothing is dispatchable, go push next word after checking for ( . likely is an overstatement but it gives better register usage
679+
if(withprob(pmask!=0,0.8)){ // If all 0, nothing is dispatchable, go push next word after checking for ( . likely is an overstatement but it gives better register usage
682680
fs1=QCWORD(fs1); // clear flags from address
683681
// We are going to execute an action routine. This will be an indirect branch, and it will mispredict. To reduce the cost of the misprediction,
684682
// we want to pile up as many instructions as we can before the branch, preferably getting out of the way as many loads as possible so that they can finish
685683
// during the pipeline restart. The perfect scenario would be that the branch restarts while the loads for the stack arguments are still loading.
686684
jt->parserstackframe.parserstkend1=stack; // Save the stackpointer in case there are calls to parse in the names we execute
687685
I pmask567=pmask; // save before we mask high bits
688-
if(pmask&=0x1F){ // if lines 0-4: decodes are mutually exclusive (i. e. one hot)
686+
if(withprob(pmask&=0x1F,0.7)){ // if lines 0-4: decodes are mutually exclusive (i. e. one hot)
689687
I fs1flag=FAV(fs1=pmask&2?fs1:fs)->flag; // if line 1, fetch V0 flags; otherwise harmless refetch of fs flags. If line 1 matches, line 0 cannot
690688
I fsflag=FAV(fs)->flag; // fetch flags early - we always need them in lines 0-2
691689
// obsolete pmask=LOWESTBIT(pmask); // leave only one bit
@@ -715,7 +713,7 @@ endname: ;
715713
// execution. That will then execute as (name' + +) creating a fork that will assign to name. So we can inplace any execution, because
716714
// it always produces a noun and the only things executable from the stack are tridents
717715
// obsolete if(unlikely((UI)fsflag>(UI)(PTISNOTASGNNAME(GETSTACK0PT)+(notfinalexec<<NOTFINALEXECX)+(~fs1flag&VASGSAFE)))){A zval;
718-
if(unlikely((UI)fsflag>(UI)(PTISNOTASGNNAME(GETSTACK0PT)+(~fs1flag&VASGSAFE)))){A zval;
716+
if(withprob((UI)fsflag>(UI)(PTISNOTASGNNAME(GETSTACK0PT)+(~fs1flag&VASGSAFE)),0.1)){A zval;
719717
// The values on the left are good: function that understands inplacing.
720718
// The values on the right are bad, and all bits > the good bits. They are: not assignment to name;
721719
// ill-behaved function (may change locales). The > means 'good and no bads', that is, inplaceable assignment

0 commit comments

Comments
 (0)