llvm.go raw

   1  package transform
   2  
   3  import (
   4  	"tinygo.org/x/go-llvm"
   5  )
   6  
   7  // Return a list of values (actually, instructions) where this value is used as
   8  // an operand.
   9  func getUses(value llvm.Value) []llvm.Value {
  10  	if value.IsNil() {
  11  		return nil
  12  	}
  13  	var uses []llvm.Value
  14  	use := value.FirstUse()
  15  	for !use.IsNil() {
  16  		uses = append(uses, use.User())
  17  		use = use.NextUse()
  18  	}
  19  	return uses
  20  }
  21  
  22  // hasUses returns whether the given value has any uses. It is equivalent to
  23  // getUses(value) != nil but faster.
  24  func hasUses(value llvm.Value) bool {
  25  	if value.IsNil() {
  26  		return false
  27  	}
  28  	return !value.FirstUse().IsNil()
  29  }
  30  
  31  // getGlobalBytes returns the slice contained in the array of the provided
  32  // global. The builder parameter is only used for constant operations.
  33  func getGlobalBytes(global llvm.Value, builder llvm.Builder) []byte {
  34  	value := global.Initializer()
  35  	buf := make([]byte, value.Type().ArrayLength())
  36  	for i := range buf {
  37  		buf[i] = byte(builder.CreateExtractValue(value, i, "").ZExtValue())
  38  	}
  39  	return buf
  40  }
  41  
  42  // stripPointerCasts strips instruction pointer casts (getelementptr and
  43  // bitcast) and returns the original value without the casts.
  44  func stripPointerCasts(value llvm.Value) llvm.Value {
  45  	if !value.IsAConstantExpr().IsNil() {
  46  		switch value.Opcode() {
  47  		case llvm.GetElementPtr, llvm.BitCast:
  48  			return stripPointerCasts(value.Operand(0))
  49  		}
  50  	}
  51  	if !value.IsAInstruction().IsNil() {
  52  		switch value.InstructionOpcode() {
  53  		case llvm.GetElementPtr, llvm.BitCast:
  54  			return stripPointerCasts(value.Operand(0))
  55  		}
  56  	}
  57  	return value
  58  }
  59