maps.go raw

   1  package transform
   2  
   3  import (
   4  	"tinygo.org/x/go-llvm"
   5  )
   6  
   7  // OptimizeMaps eliminates created but unused maps.
   8  //
   9  // In the future, this should statically allocate created but never modified
  10  // maps. This has not yet been implemented, however.
  11  func OptimizeMaps(mod llvm.Module) {
  12  	hashmapMake := mod.NamedFunction("runtime.hashmapMake")
  13  	if hashmapMake.IsNil() {
  14  		// nothing to optimize
  15  		return
  16  	}
  17  
  18  	hashmapBinarySet := mod.NamedFunction("runtime.hashmapBinarySet")
  19  	hashmapContentSet := mod.NamedFunction("runtime.hashmapContentSet")
  20  
  21  	for _, makeInst := range getUses(hashmapMake) {
  22  		updateInsts := []llvm.Value{}
  23  		unknownUses := false // are there any uses other than setting a value?
  24  
  25  		for _, use := range getUses(makeInst) {
  26  			if use := use.IsACallInst(); !use.IsNil() {
  27  				switch use.CalledValue() {
  28  				case hashmapBinarySet, hashmapContentSet:
  29  					updateInsts = append(updateInsts, use)
  30  				default:
  31  					unknownUses = true
  32  				}
  33  			} else {
  34  				unknownUses = true
  35  			}
  36  		}
  37  
  38  		if !unknownUses {
  39  			// This map can be entirely removed, as it is only created but never
  40  			// used.
  41  			for _, inst := range updateInsts {
  42  				inst.EraseFromParentAsInstruction()
  43  			}
  44  			makeInst.EraseFromParentAsInstruction()
  45  		}
  46  	}
  47  }
  48