Last active
April 19, 2017 14:36
-
-
Save kavon/b80db874cf168bd0625cdd8ef7464f56 to your computer and use it in GitHub Desktop.
CPS Call Proposal Examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;;;; | |
; (1) a complete example | |
;;;;; | |
define cc18 {i8**, i64} @foo (i8** %sp, i64 %x) noinline { | |
store i8* blockaddress (@foo, %retpt), i8** %sp | |
%retV = call cc18 {i8**, i64} @bar(i8** %sp, i64 %x) ; the 'cps' call | |
br label %retpt | |
retpt: | |
; load parameters of this block | |
%newSP.x = extractvalue {i8**, i64} %retV, 1 | |
%y.x = extractvalue {i8**, i64} %retV, 0 | |
;;;;; | |
%y = ptrtoint i8** %y.x to i64 | |
%newSP = inttoptr i64 %newSP.x to i8** | |
;;;;; | |
; perform a CPS return from @foo | |
%retAddr = load i8*, i8** %newSP | |
%retAddr1 = bitcast i8* %retAddr to {i8**, i64} (i8**, i64)* | |
%dummy = musttail call cc18 {i8**, i64} %retAddr1 (i8** %newSP, i64 %y) | |
ret {i8**, i64} %dummy | |
} | |
define cc18 {i8**, i64} @bar (i8** %sp, i64 %y) noinline { | |
%y1 = add i64 %y, 1 | |
; perform a CPS return from @bar | |
%retAddr = load i8*, i8** %sp | |
%retAddr1 = bitcast i8* %retAddr to {i8**, i64} (i8**, i64)* | |
;;;;; | |
; for fun, move SP to another register when returning | |
%sp.1 = ptrtoint i8** %sp to i64 | |
%y1.1 = inttoptr i64 %y1 to i8** | |
;;;;; | |
%dummy = musttail call cc18 {i8**, i64} %retAddr1 (i8** %y1.1, i64 %sp.1) | |
ret {i8**, i64} %dummy | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
+++++++++++++++++++++++++++++++++ | |
+ What ISEL would produce for @foo with a custom lowering of the call. | |
+ the important parts are blocked off with plus symbols | |
+ (note: the numbers are messed up but this is the basic idea) | |
+++++++++++++++++++++++++++++++++ | |
=== foo | |
Initial selection DAG: BB#0 'foo:' | |
SelectionDAG has 29 nodes: | |
t0: ch = EntryToken | |
t2: i64,ch = CopyFromReg t0, Register:i64 %vreg2 | |
t6: i64 = Constant<0> | |
t9: i64 = GlobalAddress<{ i8**, i64 } (i8**, i64)* @bar> 0 | |
t8: ch = store<ST8[%sp]> t0, BlockAddress:i64<@foo, %retpt> 0, t2, undef:i64 | |
t11: ch,glue = callseq_start t8, TargetConstant:i64<0> | |
t13: ch,glue = CopyToReg t11, Register:i64 %RSI, t2 | |
t4: i64,ch = CopyFromReg t0, Register:i64 %vreg3 | |
t15: ch,glue = CopyToReg t13, Register:i64 %R11, t4, t13:1 | |
++++++++++++++++++++++++ now a tail call ++++++++++++++++++++++++ | |
t19: ch,glue = callseq_end t18, TargetConstant:i64<0>, TargetConstant:i64<0>, t18:1 | |
t18: ch,glue = X86ISD::TC_RETURN t15, TargetGlobalAddress:i64<{ i8**, i64 } (i8**, i64)* @bar> 0, Register:i64 %RSI, Register:i64 %R11, RegisterMask:Untyped, t15:1 | |
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
Initial selection DAG: BB#1 'foo:retpt' | |
SelectionDAG has 19 nodes: | |
t0: ch = EntryToken | |
++++++++ these were sunk from BB#0, appearing after call to @bar ++++++++++ | |
t20: i64,ch,glue = CopyFromReg t19, Register:i64 %RSI, t19:1 | |
t21: i64,ch,glue = CopyFromReg t20:1, Register:i64 %R11, t20:2 | |
t22: i64,i64 = merge_values t20, t21 | |
t24: ch = CopyToReg t0, Register:i64 %vreg0, t22 | |
t26: ch = CopyToReg t0, Register:i64 %vreg1, t22:1 | |
t27: ch = TokenFactor t24, t26 | |
t28: ch = TokenFactor t27, t21:1 | |
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
t2: i64,ch = CopyFromReg t0, Register:i64 %vreg0 | |
t4: i64,ch = CopyFromReg t2:1, Register:i64 %vreg1 | |
t5: i64,i64 = merge_values t2, t4 | |
t6: i64 = Constant<0> | |
t8: i64,ch = load<LD8[%newSP]> t0, t5:1, undef:i64 | |
t10: ch,glue = callseq_start t8:1, TargetConstant:i64<0> | |
t12: ch,glue = CopyToReg t10, Register:i64 %RSI, t5:1 | |
t14: ch,glue = CopyToReg t12, Register:i64 %R11, t5, t12:1 | |
t15: ch,glue = callseq_end t14, TargetConstant:i64<0>, TargetConstant:i64<0>, t14:1 | |
t18: ch,glue = X86ISD::TC_RETURN t15, t8, Constant:i32<0>, Register:i64 %RSI, Register:i64 %R11, RegisterMask:Untyped, t15:1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
###### | |
# (3) this is currently produced by llc (with a custom cc18 convention patch) for the cps_call.ll example. | |
# I have noted the areas that should fix this output using the isel idea. | |
###### | |
.section __TEXT,__text,regular,pure_instructions | |
.macosx_version_min 10, 11 | |
.globl _foo | |
.align 4, 0x90 | |
_foo: ## @foo | |
.cfi_startproc | |
## BB#0: | |
pushq %rax | |
Ltmp0: | |
.cfi_def_cfa_offset 16 | |
leaq Ltmp1(%rip), %rax | |
movq %rax, (%rsi) | |
callq _bar # <-- will instead lower to: jmp _bar | |
movq %rsi, %rax # <-- will be sunk during isel | |
Ltmp1: ## Block address taken | |
## BB#1: ## %retpt | |
movq (%r11), %rcx | |
movq %r11, %rsi | |
movq %rax, %r11 | |
popq %rax | |
jmpq *%rcx ## TAILCALL | |
.cfi_endproc | |
.globl _bar | |
.align 4, 0x90 | |
_bar: ## @bar | |
.cfi_startproc | |
## BB#0: | |
pushq %rax | |
Ltmp2: | |
.cfi_def_cfa_offset 16 | |
movq %rsi, %rax | |
leaq 1(%r11), %rsi | |
movq (%rax), %rcx | |
movq %rax, %r11 | |
popq %rax | |
jmpq *%rcx ## TAILCALL | |
.cfi_endproc | |
.subsections_via_symbols |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment