@@ -1413,72 +1413,6 @@ func (c *Compiler) parseCall(frame *Frame, instr *ssa.CallCommon) (llvm.Value, e
1413
1413
}
1414
1414
}
1415
1415
1416
- func (c * Compiler ) emitBoundsCheck (frame * Frame , arrayLen , index llvm.Value , indexType types.Type ) {
1417
- if frame .fn .IsNoBounds () {
1418
- // The //go:nobounds pragma was added to the function to avoid bounds
1419
- // checking.
1420
- return
1421
- }
1422
-
1423
- // Sometimes, the index can be e.g. an uint8 or int8, and we have to
1424
- // correctly extend that type.
1425
- if index .Type ().IntTypeWidth () < arrayLen .Type ().IntTypeWidth () {
1426
- if indexType .(* types.Basic ).Info ()& types .IsUnsigned == 0 {
1427
- index = c .builder .CreateZExt (index , arrayLen .Type (), "" )
1428
- } else {
1429
- index = c .builder .CreateSExt (index , arrayLen .Type (), "" )
1430
- }
1431
- }
1432
-
1433
- // Optimize away trivial cases.
1434
- // LLVM would do this anyway with interprocedural optimizations, but it
1435
- // helps to see cases where bounds check elimination would really help.
1436
- if index .IsConstant () && arrayLen .IsConstant () && ! arrayLen .IsUndef () {
1437
- index := index .SExtValue ()
1438
- arrayLen := arrayLen .SExtValue ()
1439
- if index >= 0 && index < arrayLen {
1440
- return
1441
- }
1442
- }
1443
-
1444
- if index .Type ().IntTypeWidth () > c .intType .IntTypeWidth () {
1445
- // Index is too big for the regular bounds check. Use the one for int64.
1446
- c .createRuntimeCall ("lookupBoundsCheckLong" , []llvm.Value {arrayLen , index }, "" )
1447
- } else {
1448
- c .createRuntimeCall ("lookupBoundsCheck" , []llvm.Value {arrayLen , index }, "" )
1449
- }
1450
- }
1451
-
1452
- func (c * Compiler ) emitSliceBoundsCheck (frame * Frame , capacity , low , high llvm.Value , lowType , highType * types.Basic ) {
1453
- if frame .fn .IsNoBounds () {
1454
- // The //go:nobounds pragma was added to the function to avoid bounds
1455
- // checking.
1456
- return
1457
- }
1458
-
1459
- uintptrWidth := c .uintptrType .IntTypeWidth ()
1460
- if low .Type ().IntTypeWidth () > uintptrWidth || high .Type ().IntTypeWidth () > uintptrWidth {
1461
- if low .Type ().IntTypeWidth () < 64 {
1462
- if lowType .Info ()& types .IsUnsigned != 0 {
1463
- low = c .builder .CreateZExt (low , c .ctx .Int64Type (), "" )
1464
- } else {
1465
- low = c .builder .CreateSExt (low , c .ctx .Int64Type (), "" )
1466
- }
1467
- }
1468
- if high .Type ().IntTypeWidth () < 64 {
1469
- if highType .Info ()& types .IsUnsigned != 0 {
1470
- high = c .builder .CreateZExt (high , c .ctx .Int64Type (), "" )
1471
- } else {
1472
- high = c .builder .CreateSExt (high , c .ctx .Int64Type (), "" )
1473
- }
1474
- }
1475
- // TODO: 32-bit or even 16-bit slice bounds checks for 8-bit platforms
1476
- c .createRuntimeCall ("sliceBoundsCheck64" , []llvm.Value {capacity , low , high }, "" )
1477
- } else {
1478
- c .createRuntimeCall ("sliceBoundsCheck" , []llvm.Value {capacity , low , high }, "" )
1479
- }
1480
- }
1481
-
1482
1416
func (c * Compiler ) parseExpr (frame * Frame , expr ssa.Value ) (llvm.Value , error ) {
1483
1417
if value , ok := frame .locals [expr ]; ok {
1484
1418
// Value is a local variable that has already been computed.
@@ -1623,7 +1557,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
1623
1557
// Check bounds.
1624
1558
arrayLen := expr .X .Type ().(* types.Array ).Len ()
1625
1559
arrayLenLLVM := llvm .ConstInt (c .uintptrType , uint64 (arrayLen ), false )
1626
- c .emitBoundsCheck (frame , arrayLenLLVM , index , expr .Index .Type ())
1560
+ c .emitLookupBoundsCheck (frame , arrayLenLLVM , index , expr .Index .Type ())
1627
1561
1628
1562
// Can't load directly from array (as index is non-constant), so have to
1629
1563
// do it using an alloca+gep+load.
@@ -1670,7 +1604,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
1670
1604
1671
1605
// Bounds check.
1672
1606
// LLVM optimizes this away in most cases.
1673
- c .emitBoundsCheck (frame , buflen , index , expr .Index .Type ())
1607
+ c .emitLookupBoundsCheck (frame , buflen , index , expr .Index .Type ())
1674
1608
1675
1609
switch expr .X .Type ().Underlying ().(type ) {
1676
1610
case * types.Pointer :
@@ -1703,7 +1637,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
1703
1637
// Bounds check.
1704
1638
// LLVM optimizes this away in most cases.
1705
1639
length := c .builder .CreateExtractValue (value , 1 , "len" )
1706
- c .emitBoundsCheck (frame , length , index , expr .Index .Type ())
1640
+ c .emitLookupBoundsCheck (frame , length , index , expr .Index .Type ())
1707
1641
1708
1642
// Lookup byte
1709
1643
buf := c .builder .CreateExtractValue (value , 0 , "" )
0 commit comments