Polyhedral Optimization For JavaScript: The Challenges Manuel Selva - - PowerPoint PPT Presentation

polyhedral optimization for javascript the challenges
SMART_READER_LITE
LIVE PREVIEW

Polyhedral Optimization For JavaScript: The Challenges Manuel Selva - - PowerPoint PPT Presentation

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion Polyhedral Optimization For JavaScript: The Challenges Manuel Selva , Julien Pags, Philippe Clauss INRIA CAMUS, ICube, CNRS, University of


slide-1
SLIDE 1

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Polyhedral Optimization For JavaScript: The Challenges

Manuel Selva, Julien Pagès, Philippe Clauss

INRIA CAMUS, ICube, CNRS, University of Strasbourg

January 23, 2018

1 / 25

slide-2
SLIDE 2

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

The JavaScript Language

Created in 1995 at Netscape

  • To implement dynamism in web pages
  • High level and dynamic
  • ECMAScript standard

Now widely used both on client and server sides

  • For complex applications
  • Because of portability
  • Because of performances

2 / 25

5th language - PYPL index

slide-3
SLIDE 3

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

JavaScript Implementation

Engine app.js result

Widespread engines

  • SpiderMonkey - Mozilla
  • JavaScriptCore - Apple
  • V8 - Google
  • Chakra - Microsoft

3 / 25

slide-4
SLIDE 4

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

JavaScript Implementation

Engine app.js result

Widespread engines

  • SpiderMonkey - Mozilla
  • JavaScriptCore - Apple
  • V8 - Google
  • Chakra - Microsoft

Browser wars

  • Complex optimization
  • Nevertheless, no parallelism

3 / 25

slide-5
SLIDE 5

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

You Said Polyhedral Model And JavaScript Together

How to cope with dynamism?

  • Static Control Parts (SCoPs) cannot be detected statically
  • When and how detect polyhedral opportunities?

Is it worthwhile to use the polyhedral model at runtime?

  • Gain versus overhead

4 / 25

slide-6
SLIDE 6

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Outline

Motivation JavaScript Polyhedral Model And JavaScript JavaScriptCore Challenges And Solutions Detection Of SCoPs Parallel Speculation Failure Gain vs Overhead Preliminary Results

5 / 25

slide-7
SLIDE 7

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

JavaScript Is Dynamic → We Need An Engine

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

6 / 25

slide-8
SLIDE 8

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

JavaScript Is Dynamic → We Need An Engine

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

  • Types are dynamic

6 / 25

slide-9
SLIDE 9

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

JavaScript Is Dynamic → We Need An Engine

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

  • Types are dynamic
  • Arrays are dynamic

6 / 25

slide-10
SLIDE 10

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

JavaScript Is Dynamic → We Need An Engine

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

  • Types are dynamic
  • Arrays are dynamic
  • Only double precision floating point numbers

6 / 25

slide-11
SLIDE 11

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

4 Layers

f.js Bytecode compiler f.bc

  • 1. LLInt (Low Level Interpreter)

7 / 25

slide-12
SLIDE 12

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

4 Layers

f.js Bytecode compiler f.bc

  • 1. LLInt (Low Level Interpreter)
  • 2. Baseline JIT

f-v1.native

7 / 25

slide-13
SLIDE 13

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

4 Layers

f.js Bytecode compiler f.bc

  • 1. LLInt (Low Level Interpreter)
  • 2. Baseline JIT

f-v1.native f.prof

  • 3. DFG (Dataflow Graph) JIT

f-v2.native

7 / 25

slide-14
SLIDE 14

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

4 Layers

f.js Bytecode compiler f.bc

  • 1. LLInt (Low Level Interpreter)
  • 2. Baseline JIT

f-v1.native f.prof

  • 3. DFG (Dataflow Graph) JIT

f-v2.native

  • 4. FTL (Fourth Tiers LLVM) JIT

f-v3.native

7 / 25

slide-15
SLIDE 15

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

  • 1. LLInt

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

Source

8 / 25

slide-16
SLIDE 16

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

  • 1. LLInt

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

Source

f(img, width, height) { ... ...

  • p_add v 41 v;
  • p_mul v 2 v;

... ... }

Bytecode

8 / 25

slide-17
SLIDE 17

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

  • 1. LLInt

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

Source

f(img, width, height) { ... ...

  • p_add v 41 v;
  • p_mul v 2 v;

... ... }

Bytecode

while(i = next_instruction()) { switch(i->opcode) { case add: switch (type_pair(i->operand1->type(), i->operand2->type())): case number_number: i->dest = add(i->operand1, i->operand2); case object_number: i->dest = add(i->operand1->as_number(), i->operand2); ... case mul: ... } }

Interpreter

8 / 25

slide-18
SLIDE 18

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

  • 2. Baseline JIT

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

Source

f(img, width, height) { ... ...

  • p_add v 41 v;
  • p_mul v 2 v;

... ... }

Bytecode

9 / 25

slide-19
SLIDE 19

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

  • 2. Baseline JIT

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

Source

f(img, width, height) { ... ...

  • p_add v 41 v;
  • p_mul v 2 v;

... ... }

Bytecode

... switch (type_pair(v, 41)): case number_number: v = add(v, 41); case object_number: ... switch (type_pair(v, 2)): case number_number: v = mul(v->as_number() * 2); case object_number: ... ...

Native code

  • p_add v 41 v;
  • p_mul v 2 v;

9 / 25

slide-20
SLIDE 20

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

  • 3. DFG JIT

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

Source

f(img, width, height) { ... ...

  • p_add v 41 v;
  • p_mul v 2 v;

... ... }

Bytecode

10 / 25

slide-21
SLIDE 21

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

  • 3. DFG JIT

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

Source

f(img, width, height) { ... ...

  • p_add v 41 v;
  • p_mul v 2 v;

... ... }

Bytecode

if (!is_32int_array(img)) { return to Baseline JIT; } ... res = v->as_32int() + 41; if (overflow(res)) { return to Baseline JIT; } v = res; res = v->as_32int() * 2; if (overflow(res)) { return to Baseline JIT; } v = res; ...

DFG IR - Typed

10 / 25

slide-22
SLIDE 22

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

  • 3. DFG JIT

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

Source

f(img, width, height) { ... ...

  • p_add v 41 v;
  • p_mul v 2 v;

... ... }

Bytecode

if (!is_32int_array(img)) { return to Baseline JIT; } ... res = v->as_32int() + 41; if (overflow(res)) { return to Baseline JIT; } v = res; res = v->as_32int() * 2; if (overflow(res)) { return to Baseline JIT; } v = res; ...

DFG IR - Typed

... ...

Native code Homemade

  • ptim and

backend

10 / 25

slide-23
SLIDE 23

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

  • 4. FTL JIT

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

Source

f(img, width, height) { ... ...

  • p_add v 41 v;
  • p_mul v 2 v;

... ... }

Bytecode

11 / 25

slide-24
SLIDE 24

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

  • 4. FTL JIT

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

Source

f(img, width, height) { ... ...

  • p_add v 41 v;
  • p_mul v 2 v;

... ... }

Bytecode

if (!is_32int_array(img)) { return to Baseline JIT; } ... res = v->as_32int() + 41; if (overflow(res)) { return to Baseline JIT; } v = res; res = v->as_32int() * 2; if (overflow(res)) { return to Baseline JIT; } v = res; ...

LLVM IR - Typed

11 / 25

slide-25
SLIDE 25

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

  • 4. FTL JIT

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j]; v = v + 41; v = v * 2; img[i*width + j] = v; } } }

Source

f(img, width, height) { ... ...

  • p_add v 41 v;
  • p_mul v 2 v;

... ... }

Bytecode

if (!is_32int_array(img)) { return to Baseline JIT; } ... res = v->as_32int() + 41; if (overflow(res)) { return to Baseline JIT; } v = res; res = v->as_32int() * 2; if (overflow(res)) { return to Baseline JIT; } v = res; ...

LLVM IR - Typed

... ...

Native code LLVM

  • ptim and

backend

11 / 25

slide-26
SLIDE 26

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Proposal

Add polyhedral optimization in JavaScriptCore

  • In the last layer - FTL
  • Dynamism has been removed
  • Polly
  • Polyhedral optimizer for LLVM
  • Transform LLVM IR to optimized LLVM IR

12 / 25

slide-27
SLIDE 27

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Outline

Motivation JavaScript Polyhedral Model And JavaScript JavaScriptCore Challenges And Solutions Detection Of SCoPs Parallel Speculation Failure Gain vs Overhead Preliminary Results

13 / 25

slide-28
SLIDE 28

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

SESE Regions: Problem - Apply To All Engines

for.j.header: ... idx = i*width + j idx > img_size T F

  • ut.of.bounds:

handleSpecFail()

  • ut.of.bounds:

handleSpecFail() get.address: ... isHole(img[idx]) T F load.from.hole: handleSpecFail() add: ... res = add op1 op2

  • verflow(res)

T F

  • verflow:

handleSpecFail() mul: .. res = mul op1 op2

  • verflow(res)

T F

  • verflow:

handleSpecFail() inc: j = j + 1 j < width F T

f(img, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; i++) { var v = img[i*width + j] v = v + 41; v = v * 2; img[i*width + j] = v; } } }

Source

14 / 25

slide-29
SLIDE 29

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

SESE Regions: Solution

for.j.header: ... idx = i*width + j idx > img_size T F

  • ut.of.bounds:

handleSpecFail()

  • ut.of.bounds:

handleSpecFail() get.address: ... isHole(img[idx]) T F load.from.hole: handleSpecFail() add: ... res = add op1 op2

  • verflow(res)

T F

  • verflow:

handleSpecFail() mul: .. res = mul op1 op2

  • verflow(res)

T F

  • verflow:

handleSpecFail() inc: j = j + 1 j < width F T

Step 1 (in our implementation)

  • Tag instructions branching to exit

blocks

15 / 25

slide-30
SLIDE 30

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

SESE Regions: Solution

for.j.header: ... idx = i*width + j idx > img_size

  • ut.of.bounds:

handleSpecFail()

  • ut.of.bounds:

handleSpecFail() get.address: ... isHole(img[idx]) load.from.hole: handleSpecFail() add: ... res = add op1 op2

  • verflow(res)
  • verflow:

handleSpecFail() mul: .. res = mul op1 op2

  • verflow(res)
  • verflow:

handleSpecFail() inc: j = j + 1 j < width

Step 1 (in our implementation)

  • Tag instructions branching to exit

blocks

  • Remove exit blocks
  • Perform polyhedral optimization

15 / 25

slide-31
SLIDE 31

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

SESE Regions: Solution

for.j.header: ... idx = i*width + j idx > img_size T F

  • ut.of.bounds:

handleSpecFail()

  • ut.of.bounds:

handleSpecFail() get.address: ... isHole(img[idx]) T F load.from.hole: handleSpecFail() add: ... res = add op1 op2

  • verflow(res)

T F

  • verflow:

handleSpecFail() mul: .. res = mul op1 op2

  • verflow(res)

T F

  • verflow:

handleSpecFail() inc: j = j + 1 j < width F T

Step 1 (in our implementation)

  • Tag instructions branching to exit

blocks

  • Remove exit blocks
  • Perform polyhedral optimization

Step 2 (not yet completed)

  • Add back exit blocks from tagged

instructions

15 / 25

slide-32
SLIDE 32

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Two Dimensional Arrays And Arrays Of Objects

Problem - Apply to all engines

t[i].foo = 17; t[i][j] = 17; → 2 memory accesses

16 / 25

slide-33
SLIDE 33

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Two Dimensional Arrays And Arrays Of Objects

Problem - Apply to all engines

t[i].foo = 17; t[i][j] = 17; → 2 memory accesses

Solutions

  • Do not handle them (in our implementation)
  • Inspector / executor
  • Modify language and object allocator

16 / 25

slide-34
SLIDE 34

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Handling inttoptr And sext Instructions

Problem - Specific to JavaScriptCore and Polly

  • Polly is designed for LLVM IR coming from frontends for

static languages

  • intoptr used by the runtime for known addresses
  • sext used by the runtime for values representation (NaN

boxing)

  • inttoptr and sext instructions make SCoP detection fail

Solution (in our implementation)

  • Modify Polly to support these instructions

17 / 25

slide-35
SLIDE 35

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Parallel Speculation

Problem - Apply to all engines

  • Speculation failure in one thread
  • Other threads may have performed wrong computation

Solutions

  • Ignore speculation failure (in our implementation) - Wrong!
  • Only optimize idempotent regions
  • Save and rollback

18 / 25

slide-36
SLIDE 36

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Gain vs Overhead - Problem - Apply To All Engines

Execution time of optimized version + Polly optimization time < Execution time of original version

19 / 25

slide-37
SLIDE 37

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Solution - JavaScriptCore Cost Model + Parallel Compil.

f.bc

  • 1. LLInt interpretation
  • 2. Baseline compilation
  • 2. Baseline execution
  • 3. DFG compilation
  • 3. DFG Execution
  • 4. FTL compilation
  • 4. FTL execution

time threads

20 / 25

  • Number of function calls
  • Number of instructions

executed

slide-38
SLIDE 38

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Outline

Motivation JavaScript Polyhedral Model And JavaScript JavaScriptCore Challenges And Solutions Detection Of SCoPs Parallel Speculation Failure Gain vs Overhead Preliminary Results

21 / 25

slide-39
SLIDE 39

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Matrix Multiply - Transformations

matmul(left, right, res, left_nblines, left_nbcols, right_nbcols) { for (var i = 0; i < left_nblines; i++) { for (var j = 0; j < left_nbcols; j++) { var idx_left = i * left_nbcols + j; for (var k = 0; k < right_nbcols; k++) { var idx_res = i*right_nbcols + k; var idx_right = j*right_nbcols + k; res[idx_res] = res[idx_res] + left[idx_left]*right[idx_right]; } } } }

22 / 25

slide-40
SLIDE 40

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Matrix Multiply - Transformations

matmul(left, right, res, left_nblines, left_nbcols, right_nbcols) { for (var i = 0; i < left_nblines; i++) { for (var j = 0; j < left_nbcols; j++) { var idx_left = i * left_nbcols + j; for (var k = 0; k < right_nbcols; k++) { var idx_res = i*right_nbcols + k; var idx_right = j*right_nbcols + k; res[idx_res] = res[idx_res] + left[idx_left]*right[idx_right]; } } } } if(alias test ok){ #pragma omp parallel for for(c0 = 0; c0 <= floord(p2-1, 32); c0 += 1) for(c1 = 0; c1 <= floord(p1-1, 32); c1 += 1) for(c2 = 0; c2 <= floord(p0-1, 32); c2 += 1) { for(c3 = 0; c3 <= min(31, p2-32*c0-1); c3 += 1) for(c4 = 0; c4 <= min(31, p1-32*c1-1); c4 += 1) for(c5 = 0; c5 <= min(31, p0-32*c2-1); c5 += 1) Stmt_68(32*c0+c3, 32*c2+c5, 32*c1+c4); } else { original code version }

22 / 25

slide-41
SLIDE 41

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Matrix Multiply - Performances

Setup

  • Intel Xeon W3520 with 4 cores running Linux 4.4.0
  • LLVM and Polly 4.0.0 with –-parallel
  • matmul function called twice
  • Right matrix size is 3000x300

Results

Size of Execution time Execution time Speedup left matrix without Polly (s) with Polly (s) 50x3000 0.08 0.06 1.33 500x3000 0.85 0.22 3.86 2000x3000 3.3 0.87 3.79

23 / 25

slide-42
SLIDE 42

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

Conclusion

Polyhedral optimization for JavaScript is almost there

  • Speedups shown on a matrix multiply kernel

Ongoing work

  • Complete implementation
  • Evaluate speedups on real applications
  • Study how to enrich JavaScriptCore profiling to help

polyhedral optimizer

24 / 25

slide-43
SLIDE 43

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

An Other Conclusion

JavaScript is a dynamic language. To efficiently execute it, dynamic features must not be used too often. Engineers at Google writing the V8 engine even recommend1 to: “Write code that looks like statically typed”

1Franziska Hinkelmann at JS Conf EU 2017 25 / 25

slide-44
SLIDE 44

Motivation JavaScriptCore Proposal Challenges And Solutions Preliminary Results Conclusion

An Other Conclusion

JavaScript is a dynamic language. To efficiently execute it, dynamic features must not be used too often. Engineers at Google writing the V8 engine even recommend1 to: “Write code that looks like statically typed” WebAssembly

1Franziska Hinkelmann at JS Conf EU 2017 25 / 25

slide-45
SLIDE 45

Backup

BACKUP

26 / 25

slide-46
SLIDE 46

Backup

Tiers-Up In JavaScriptCore

LLInt → Baseline

  • Same program state (variables values) representation
  • OSR entry = jump (nothing to do)
  • At any bytecode instruction

Baseline → DFG

  • Different program state representations
  • OSR entry = jump + copy of the state
  • Only at function entry and loop header

DFG → FTL

  • Different program state representations
  • OSR entry = jump + copy of the state
  • Only at function entry and loop header
  • Two code versions

27 / 25

slide-47
SLIDE 47

Backup

NaN-Boxing In JavaScriptCore

Tag Payload IEE-754 doubles

  • 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0

JavaScriptCore doubles . . . . . . . . . . . . . . . . . . . F F F 8 | F F F F | F F F F | F F F F IEE-754 NaN

                            

F F F 9 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 JavaScriptCore NaN . . . . . . . . . . . . . . . . . . . F F F D | F F F F | F F F F | F F F F F F F E | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 JavaScriptCore 32-bits integers . . . . . . . . . . . . . . . . . . . F F F E | 0 0 0 0 | F F F F | F F F F . . . . . . . . . . . . . . . . . . . Not used F F F F | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 JavaScriptCore pointers . . . . . . . . . . . . . . . . . . . F F F F | F F F F | F F F F | F F F F

  • Direct manipulation of doubles
  • Indirect manipulation (masking) of pointers
  • Indirecte manipulation (masking) 32 bits integers

28 / 25

slide-48
SLIDE 48

Backup

NaN-Boxing In JavaScriptCore

Tag Payload IEE-754 doubles

  • 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0

JavaScriptCore doubles . . . . . . . . . . . . . . . . . . . F F F 8 | F F F F | F F F F | F F F F IEE-754 NaN

                            

F F F 9 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 JavaScriptCore NaN . . . . . . . . . . . . . . . . . . . F F F D | F F F F | F F F F | F F F F F F F E | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 JavaScriptCore 32-bits integers . . . . . . . . . . . . . . . . . . . F F F E | 0 0 0 0 | F F F F | F F F F . . . . . . . . . . . . . . . . . . . Not used F F F F | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 JavaScriptCore pointers . . . . . . . . . . . . . . . . . . . F F F F | F F F F | F F F F | F F F F

  • Direct manipulation of doubles
  • Indirect manipulation (masking) of pointers
  • Indirecte manipulation (masking) 32 bits integers

28 / 25

Favor pointers

  • +248 = 0001|0000|0000|0000 =

281474976710656

slide-49
SLIDE 49

Backup

NaN-Boxing In JavaScriptCore

Tag Payload IEE-754 doubles

  • 0 0 0 1 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0

JavaScriptCore doubles . . . . . . . . . . . . . . . . . . . F F F 9 | F F F F | F F F F | F F F F IEE-754 NaN

                            

F F F A | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 JavaScriptCore NaN . . . . . . . . . . . . . . . . . . . F F F E | F F F F | F F F F | F F F F F F F F | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 JavaScriptCore 32-bits integers . . . . . . . . . . . . . . . . . . . F F F F | 0 0 0 0 | F F F F | F F F F . . . . . . . . . . . . . . . . . . . Not used 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 JavaScriptCore pointers . . . . . . . . . . . . . . . . . . . 0 0 0 0 | F F F F | F F F F | F F F F

  • Direct manipulation of pointers
  • Indirect manipulation (substraction) of doubles
  • Indirect manipulation (masking) of 32 bits integers

29 / 25

slide-50
SLIDE 50

Backup

NaN-Boxing In JavaScriptCore

  • DoubleEncodeOffset
  • Favor pointers
  • 0001|0000|0000|0000 = +281474976710656 = +248
  • TagTypeNumber
  • If all bits in the mask are set, this indicates an integer
  • If any but not all are set this value is a double.
  • FFFF|0000|0000|0000 = −281474976710656
  • TagMask = TagTypeNumber | TagBitTypeOther
  • Used to check for all types of immediate values
  • Either number or other immediate (bool, null, undefined)
  • FFFF|0000|0000|0002 = −281474976710654
  • add DoubleEncodeOffset ≡ sub TagTypeNumber

30 / 25

slide-51
SLIDE 51

Backup

JavaScriptCore History

Developed by Apple

  • Included in WebKit, LGPL license
  • Before 2008 - SquirrelFish interpreter
  • 2008 - 2014 - Nitro JIT
  • 2014 - FTL JIT based on LLVM
  • Mid 2016 - FTL replaced by B3, home made JIT and backend

Big project

LOC per language: cpp: 289 435 (89.38%) ansic: 11 254 (3.48%) ruby: 9 925 (3.06%) python: 6 195 (1.91%) asm: 4 982 (1.54%) perl: 2 013 (0.62%) sh: 24 (0.01%) LOC Total: 323 828

31 / 25

slide-52
SLIDE 52

Backup

Polly: Polyhedral Optimization for LLVM

IR LLVM

1 2 3 4 5 1 2 3 i j 1 2 3 4 5 1 2 3 t p

IR LLVM Optimized Modeling Transformation Code Generation

32 / 25

slide-53
SLIDE 53

Backup

Detection Of Affine Accesses To Arrays

Problem - Specific to JavaScriptCore and Polly

t[index] = 17; %offset = shl i64 %index, 3 %cell_as_int = add i64 %base_as_int, %offset %cell_ptr = inttoptr i64 %cell_as_int to i64* store i64 %boxed_17, i64* %cell_ptr

33 / 25

slide-54
SLIDE 54

Backup

Detection Of Affine Accesses To Arrays

Problem - Specific to JavaScriptCore and Polly

t[index] = 17; %offset = shl i64 %index, 3 %cell_as_int = add i64 %base_as_int, %offset %cell_ptr = inttoptr i64 %cell_as_int to i64* store i64 %boxed_17, i64* %cell_ptr

Solution (in our implementation)

%base_ptr = inttoptr i64 %base_as_int to [1000 x i64]* %cell_ptr = getelementptr [1000 x i64], [1000 x i64]* %base_ptr, i32 0, i32 %index store i64 %boxed_17, i64* %cell_ptr

33 / 25