Check-in [2b2ba21e34]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Finish up return from an invoked function. Still need to do invoked commands and invokeExpanded in the NRE case.
Timelines: family | ancestors | descendants | both | notworking | kbk-nre
Files: files | file ages | folders
SHA3-256:2b2ba21e34d761d3d6a8c564cdc7ce318bbc677883e8e84b8a3cfaf85de1d8b3
User & Date: kbk 2018-04-14 22:10:45
Context
2018-04-15
03:07
Finish coding the thunk builder for NRE procs. Generated code for NRE now aborts in the optimizer. check-in: ab703b4b95 user: kbk tags: notworking, kbk-nre
2018-04-14
22:19
Finish up return from an invoked function. Still need to do invoked commands and invokeExpanded in the NRE case. Closed-Leaf check-in: bcc7273e40 user: kbk tags: mistake, notworking
22:10
Finish up return from an invoked function. Still need to do invoked commands and invokeExpanded in the NRE case. check-in: 2b2ba21e34 user: kbk tags: notworking, kbk-nre
2018-04-13
01:58
Merge trunk, and do some further tidying of objv management check-in: 1fac62e1ab user: kbk tags: notworking, kbk-nre
Changes

Changes to codegen/compile.tcl.

1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
....
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403






1404
1405

1406
1407
1408
1409
1410



1411


1412
1413
1414






























































1415
1416
1417
1418
1419
1420
1421
....
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
    # Results:
    #	The set of arguments that might have been consumed in the operation
    #	(for cleanup by the caller of this method).

    method IssueInvoke {callframe operation} {
	set arguments [lassign $operation opcode tgt thecallframe origname]
	set vname [my LocalVarName $tgt]

	set called [my ResolveInvoke \
			[dict get $vtypes $tgt] $origname $arguments]
	if {$called ne {}} {
	    set argvals [lmap arg $arguments {my LoadOrLiteral $arg}]
	    my IssueInvokeFunction $tgt $called $argvals $vname
	    return {}
	} else {
................................................................................
    #
    # Results:
    #	Returns the set of arguments that might have been consumed in the
    #	call (for cleanup by the caller of this method).

    method IssueNREReturnFromInvoke {callframe operation} {

	error "Kevin is here... this isn't done!"

	set arguments [lassign $operation opcode tgt thecallframe origname]
	set rettype [lindex $opcode 1]
	set vname [my LocalVarName $tgt]
	set called [my ResolveInvoke $rettype $origname $arguments]






	if {$called ne {}} {
	    my IssueNREReturnFromInvokedFunction $rettype $tgt $called $vname

	    return {}
	} else {
	    set arguments [linsert $arguments[set arguments ""] 0 $origname]
	    set argvals [lmap arg $arguments {my LoadOrLiteral $arg}]
	    my IssueNREInvokeCommand $rettype $tgt $arguments $argvals $vname



	    return $arguments


	}
    }































































 
    # TclCompiler:ResolveInvoke --
    #
    #	Determines whether an invoked command is known as a compiled
    #	function, and resolves it if it is.
    #
    # Parameters:
................................................................................
	    switch [lindex $quads $search 0] {
		"free" {
		    if {[lindex $quads $search 2] eq $var} {
			return $search
		    }
		}
		"jump" - "jumpFalse" - "jumpTrue" - "return" -
		"jumpMaybe" - "jumpMaybeNot" {
		    return 0
		}
		default {
		    if {$var in [lindex $quads $search]} {
			return 0
		    }
		}







<







 







<
<
|
|


>
>
>
>
>
>

|
>



|
|
>
>
>

>
>


|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







1272
1273
1274
1275
1276
1277
1278

1279
1280
1281
1282
1283
1284
1285
....
1390
1391
1392
1393
1394
1395
1396


1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
....
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
    # Results:
    #	The set of arguments that might have been consumed in the operation
    #	(for cleanup by the caller of this method).

    method IssueInvoke {callframe operation} {
	set arguments [lassign $operation opcode tgt thecallframe origname]
	set vname [my LocalVarName $tgt]

	set called [my ResolveInvoke \
			[dict get $vtypes $tgt] $origname $arguments]
	if {$called ne {}} {
	    set argvals [lmap arg $arguments {my LoadOrLiteral $arg}]
	    my IssueInvokeFunction $tgt $called $argvals $vname
	    return {}
	} else {
................................................................................
    #
    # Results:
    #	Returns the set of arguments that might have been consumed in the
    #	call (for cleanup by the caller of this method).

    method IssueNREReturnFromInvoke {callframe operation} {



	set arguments [lassign $operation opcode tgt corohandle origname]
	set rettype [dict get $vtypes $tgt]
	set vname [my LocalVarName $tgt]
	set called [my ResolveInvoke $rettype $origname $arguments]
	puts "IssueNREReturnFromInvoke:"
	puts "  tgt = $tgt"
	puts "  rettype = $rettype = [nameOfType $rettype]"
	puts "  origname = $origname"
	puts "  vname = $vname"
	puts "  called = $called"
	if {$called ne {}} {
	    my IssueNREReturnFromInvokedFunction \
		$rettype $tgt $corohandle $callframe $called $arguments $vname
	    return {}
	} else {
	    set arguments [linsert $arguments[set arguments ""] 0 $origname]
	    set i -1
	    my IssueNREReturnFromInvokedCommand \
		$rettype $tgt $corohandle $callframe $arguments $vname
	    ;				# objc will still contain
	    ;				# argument values
	    return $arguments
	    ;				# FIXME: gotta work through the
	    ;			 	# refcounting 
	}
    }
 
    # TclCompiler:IssueNREReturnFromInvokedFunction --
    #
    #	Generates code to return from compiled NRE code.
    #
    # Parameters:
    #	rettype - Return type of the function
    #   tgt - Quadcode value representing the return value
    #	corohandle - Coroutine handle of the function that's just returned
    #	callframe - The current callframe
    #	called - Quadcode value giving the name of the function that was called
    #   arguments - List of quadcode values representing the arguments
    #	vname - LLVM name to assign to the result of the call
    #
    # Results:
    #	None.

    method IssueNREReturnFromInvokedFunction {rettype tgt corohandle callframe
					      called arguments vname} {

	# Built-in types that are handled here.
	set BASETYPES {ZEROONE INT DOUBLE NUMERIC STRING}
	set ts [lmap t $BASETYPES {Type $t?}]
	set tgttype [my ValueTypes $tgt]

	# Get the name of the function to call
	set callee [my GenerateFunctionName $tgt arguments $arguments]

	# Emit the sequence that destroys the LLVM coroutine and returns the
	# result as 'retval'
	lassign [my returnedFromCoro $rettype $callee $corohandle] \
	    retcode retval

	# Handle the return

	if {$tgttype eq "FAIL"} {
	    # This procedure only ever fails.
	    $b store $retval $errorCode
	    my SetErrorLine $errorCode
	} else {
	    set restype [TypeOf $retval]; # LLVM type ref of the return val
	    puts "Result type is $restype and target type is $tgttype"
	    puts "How could they be different?"
	    if {$restype in $ts} {
		puts "The called function returns a known type"
		$b store [$b extract $retval 0] $errorCode
	    } elseif {[Type $restype?] eq [Type $tgttype]} {
		puts "The called function returns a MAYBE"
		set retval [$b ok $reval]
	    }
	    if {"FAIL" in $tgttype} {
		puts "Result might have failed, set error line"
		my SetErrorLine $errorCode [$b maybe $retval]
	    }
	}

	# Pack a callframe reference with the return if needed

	if {"CALLFRAME" in $tgttype} {
	    puts "Result includes an updated callframe"
	    set result [$b frame.pack $callframe $result]
	}
    }
 
    # TclCompiler:ResolveInvoke --
    #
    #	Determines whether an invoked command is known as a compiled
    #	function, and resolves it if it is.
    #
    # Parameters:
................................................................................
	    switch [lindex $quads $search 0] {
		"free" {
		    if {[lindex $quads $search 2] eq $var} {
			return $search
		    }
		}
		"jump" - "jumpFalse" - "jumpTrue" - "return" -
		"jumpMaybe" - "jumpMaybeNot" - "NRE.suspend" {
		    return 0
		}
		default {
		    if {$var in [lindex $quads $search]} {
			return 0
		    }
		}

Changes to codegen/coro.tcl.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
271
272
273
274
275
276
277
278

279









280
281
282
283
284
285
286
287
288
289
290
291
292
293
294









































295
296
297
298
299
300
301
 
oo::define Builder {

    # Implementation of various support functions needed to support Tcl's
    # coroutines

    variable tcl.coro.runner
    variable tcl.coro.addCallbackToCoroRunner 

}
 
# Builder method @coroFunctions --
#
#	Defines support functions for LLVM coroutines that need to be in
#	LLVM assembly language.
................................................................................
}
 
# TclCompiler method CoroPromiseType --
#
#	Generates the LLVM type that represents the coroutine promise for
#	the current NRE function

oo::define TclCompiler method CoroPromiseType {} {

    set realname [my GenerateFunctionName $cmd typecodes $paramTypes]









    return \
	[Type named\{${realname}.promise,status:int32,retval:[nameOfType $returnType]\}]
}
 
# Builder method launchCoroRunner --
#
#	Generates code to launch the Tcl_NRAddCallback chain that executes
#	the LLVM coroutine representing a Tcl command invocation.
#
# Parameters:
#	handle - LLVM value reference specifying the LLVM coroutine handle

oo::define Builder method launchCoroRunner {handle} {
    my call ${tcl.coro.addCallbackToCoroRunner} $handle
}









































 
# TclCompiler method CoroSuspend --
#
#	Generates code to suspend the current coroutine and resume at a
#	specified basic block.
#
# Parameters:







|







 







|
>
|
>
>
>
>
>
>
>
>
>
|
<













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290

291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
 
oo::define Builder {

    # Implementation of various support functions needed to support Tcl's
    # coroutines

    variable tcl.coro.runner
    variable tcl.coro.addCallbackToCoroRunner

}
 
# Builder method @coroFunctions --
#
#	Defines support functions for LLVM coroutines that need to be in
#	LLVM assembly language.
................................................................................
}
 
# TclCompiler method CoroPromiseType --
#
#	Generates the LLVM type that represents the coroutine promise for
#	the current NRE function

oo::define TclCompiler method CoroPromiseType {{rettype {}} {realname {}}} {
    if {$realname eq {}} {
	set realname [my GenerateFunctionName $cmd typecodes $paramTypes]
    }
    if {$rettype eq {}} {
	set rettype $returnType
    }
    set typestr named 
    append typestr \{ $realname .promise
    append typestr , status:int32
    append typestr , retval: [nameOfType $rettype]
    append typestr \}
    return [Type $typestr]

}
 
# Builder method launchCoroRunner --
#
#	Generates code to launch the Tcl_NRAddCallback chain that executes
#	the LLVM coroutine representing a Tcl command invocation.
#
# Parameters:
#	handle - LLVM value reference specifying the LLVM coroutine handle

oo::define Builder method launchCoroRunner {handle} {
    my call ${tcl.coro.addCallbackToCoroRunner} $handle
}
 
# TclCompiler method returnFromCoro --
#
#	Generates code to retrieve the status and return value from
#	a coroutine that has done the final suspend.
#
# Parameters:
#	rettype - The function's return type
#	callee - The name of the function that has been called
#
# Results:
#	Returns a list of two LLVM value refs: the status code and the
#	return value.

oo::define TclCompiler method returnedFromCoro {rettype callee corohandle} {

    # Retrieve the coroutine promise from the coroutine handle

    set handle [my LoadOrLiteral $corohandle]
    set ptype [my CoroPromiseType $rettype $callee]
    set alignment [$b cast(int) [AlignOf $ptype] "alignment"]
    set paddr_raw [$b call [$m intrinsic coro.promise] \
		       [list $handle $alignment [Const false bool]] \
		       "promise.addr.raw"]
    set paddr [$b cast(ptr) $paddr_raw $ptype "promise.addr"]

    # Retrieve the return code and return value of the called procedure

    set rcodeaddr [$b gep $paddr 0 0]
    set rcode [$b load $rcodeaddr "return.code"]
    set rvaladdr [$b gep $paddr 0 1]
    set rval [$b load $rvaladdr "return.value"]

    # Destroy the coroutine - we're done with it now.

    $b call [$m intrinsic coro.destroy] [list $handle]

    # Return the status and result

    return [list $rcode $rval]
}
 
# TclCompiler method CoroSuspend --
#
#	Generates code to suspend the current coroutine and resume at a
#	specified basic block.
#
# Parameters: