[llgo] Update to use the latest IR attribute bindings

A recent commit (r286087) to the LLVM Go bindings that
changed things over to use the new attribute API broke
llgo.  This commit updates llgo accordingly.

llvm-svn: 288769
GitOrigin-RevId: 21e53508b63c3192d293dff806b26771d100f214
diff --git a/cmd/gllgo/gllgo.go b/cmd/gllgo/gllgo.go
index a93cb1d..88a5be3 100644
--- a/cmd/gllgo/gllgo.go
+++ b/cmd/gllgo/gllgo.go
@@ -154,16 +154,21 @@
 }
 
 func (san *sanitizerOptions) getAttribute() llvm.Attribute {
+	var attrKind uint
+
 	switch {
 	case san.address:
-		return llvm.SanitizeAddressAttribute
+		attrKind = llvm.AttributeKindID("sanitize_address")
 	case san.thread:
-		return llvm.SanitizeThreadAttribute
+		attrKind = llvm.AttributeKindID("sanitize_thread")
 	case san.memory:
-		return llvm.SanitizeMemoryAttribute
+		attrKind = llvm.AttributeKindID("sanitize_memory")
 	default:
-		return 0
+		attrKind = 0
 	}
+
+	ctx := llvm.GlobalContext()
+	return ctx.CreateEnumAttribute(attrKind, 0)
 }
 
 type driverOptions struct {
diff --git a/irgen/attribute.go b/irgen/attribute.go
index c9d5393..9fd6f61 100644
--- a/irgen/attribute.go
+++ b/irgen/attribute.go
@@ -148,25 +148,27 @@
 	for _, field := range strings.Fields(value) {
 		switch strings.ToLower(field) {
 		case "noreturn":
-			result |= llvmAttribute(llvm.NoReturnAttribute)
 		case "nounwind":
-			result |= llvmAttribute(llvm.NoUnwindAttribute)
 		case "noinline":
-			result |= llvmAttribute(llvm.NoInlineAttribute)
 		case "alwaysinline":
-			result |= llvmAttribute(llvm.AlwaysInlineAttribute)
+			kind := llvm.AttributeKindID(strings.ToLower(field))
+			result.AttrKinds = append(result.AttrKinds, kind)
 		}
 	}
 	return result
 }
 
-type llvmAttribute llvm.Attribute
+type llvmAttribute struct {
+	AttrKinds []uint
+}
 
 func (a llvmAttribute) Apply(v llvm.Value) {
+	ctx := v.GlobalParent().Context()
 	if !v.IsAFunction().IsNil() {
-		v.AddFunctionAttr(llvm.Attribute(a))
-	} else {
-		v.AddAttribute(llvm.Attribute(a))
+		for _, kind := range a.AttrKinds {
+			attr := ctx.CreateEnumAttribute(kind, 0)
+			v.AddFunctionAttr(attr)
+		}
 	}
 }
 
diff --git a/irgen/cabi.go b/irgen/cabi.go
index ba3b09f..610f63d 100644
--- a/irgen/cabi.go
+++ b/irgen/cabi.go
@@ -249,6 +249,7 @@
 
 	switch bt := bt.(type) {
 	case *structBType, *arrayBType:
+		noneAttr := tm.ctx.CreateEnumAttribute(0, 0)
 		bo := tm.getBackendOffsets(bt)
 		sp := 0
 		for sp != len(bo) && bo[sp].offset < 8 {
@@ -258,21 +259,23 @@
 		eb2 := bo[sp:]
 		if len(eb2) > 0 {
 			argTypes = append(argTypes, tm.classifyEightbyte(eb1, &numInt, &numSSE), tm.classifyEightbyte(eb2, &numInt, &numSSE))
-			argAttrs = append(argAttrs, 0, 0)
+			argAttrs = append(argAttrs, noneAttr, noneAttr)
 		} else {
 			argTypes = append(argTypes, tm.classifyEightbyte(eb1, &numInt, &numSSE))
-			argAttrs = append(argAttrs, 0)
+			argAttrs = append(argAttrs, noneAttr)
 		}
 
 		return argTypes, argAttrs, numInt, numSSE
 
 	case *intBType:
 		if bt.width < 4 {
+			var argAttrKind uint
 			if bt.signed {
-				argAttr = llvm.SExtAttribute
+				argAttrKind = llvm.AttributeKindID("signext")
 			} else {
-				argAttr = llvm.ZExtAttribute
+				argAttrKind = llvm.AttributeKindID("zeroext")
 			}
+			argAttr = tm.ctx.CreateEnumAttribute(argAttrKind, 0)
 		}
 	}
 
@@ -516,10 +519,12 @@
 
 func (fi *functionTypeInfo) declare(m llvm.Module, name string) llvm.Value {
 	fn := llvm.AddFunction(m, name, fi.functionType)
-	fn.AddFunctionAttr(fi.retAttr)
+	if fi.retAttr.GetEnumKind() != 0 {
+		fn.AddAttributeAtIndex(0, fi.retAttr)
+	}
 	for i, a := range fi.argAttrs {
-		if a != 0 {
-			fn.Param(i).AddAttribute(a)
+		if a.GetEnumKind() != 0 {
+			fn.AddAttributeAtIndex(i + 1, a)
 		}
 	}
 	return fn
@@ -537,9 +542,13 @@
 	fi.retInf.prepare(ctx, allocaBuilder, callArgs)
 	typedCallee := builder.CreateBitCast(callee, llvm.PointerType(fi.functionType, 0), "")
 	call := builder.CreateCall(typedCallee, callArgs, "")
-	call.AddInstrAttribute(0, fi.retAttr)
+	if fi.retAttr.GetEnumKind() != 0 {
+		call.AddCallSiteAttribute(0, fi.retAttr)
+	}
 	for i, a := range fi.argAttrs {
-		call.AddInstrAttribute(i+1, a)
+		if a.GetEnumKind() != 0 {
+			call.AddCallSiteAttribute(i + 1, a)
+		}
 	}
 	return fi.retInf.decode(ctx, allocaBuilder, builder, call)
 }
@@ -556,9 +565,13 @@
 	fi.retInf.prepare(ctx, allocaBuilder, callArgs)
 	typedCallee := builder.CreateBitCast(callee, llvm.PointerType(fi.functionType, 0), "")
 	call := builder.CreateInvoke(typedCallee, callArgs, cont, lpad, "")
-	call.AddInstrAttribute(0, fi.retAttr)
+	if fi.retAttr.GetEnumKind() != 0 {
+		call.AddCallSiteAttribute(0, fi.retAttr)
+	}
 	for i, a := range fi.argAttrs {
-		call.AddInstrAttribute(i+1, a)
+		if a.GetEnumKind() != 0 {
+			call.AddCallSiteAttribute(i + 1, a)
+		}
 	}
 	builder.SetInsertPointAtEnd(cont)
 	return fi.retInf.decode(ctx, allocaBuilder, builder, call)
@@ -567,6 +580,7 @@
 func (tm *llvmTypeMap) getFunctionTypeInfo(args []types.Type, results []types.Type) (fi functionTypeInfo) {
 	var returnType llvm.Type
 	var argTypes []llvm.Type
+	var argAttrKind uint
 	if len(results) == 0 {
 		returnType = llvm.VoidType()
 		fi.retInf = &directRetInfo{}
@@ -609,7 +623,8 @@
 		case AIK_Indirect:
 			returnType = llvm.VoidType()
 			argTypes = []llvm.Type{llvm.PointerType(resultsType, 0)}
-			fi.argAttrs = []llvm.Attribute{llvm.StructRetAttribute}
+			argAttrKind = llvm.AttributeKindID("sret")
+			fi.argAttrs = []llvm.Attribute{tm.ctx.CreateEnumAttribute(argAttrKind, 0)}
 			fi.retInf = &indirectRetInfo{numResults: len(results), resultsType: resultsType}
 		}
 	}
@@ -617,7 +632,8 @@
 	// Allocate an argument for the call chain.
 	fi.chainIndex = len(argTypes)
 	argTypes = append(argTypes, llvm.PointerType(tm.ctx.Int8Type(), 0))
-	fi.argAttrs = append(fi.argAttrs, llvm.NestAttribute)
+	argAttrKind = llvm.AttributeKindID("nest")
+	fi.argAttrs = append(fi.argAttrs, tm.ctx.CreateEnumAttribute(argAttrKind, 0))
 
 	// Keep track of the number of INTEGER/SSE class registers remaining.
 	remainingInt := 6
@@ -651,7 +667,8 @@
 		if !isDirect {
 			fi.argInfos = append(fi.argInfos, &indirectArgInfo{len(argTypes)})
 			argTypes = append(argTypes, llvm.PointerType(tm.ToLLVM(arg), 0))
-			fi.argAttrs = append(fi.argAttrs, llvm.ByValAttribute)
+			argAttrKind = llvm.AttributeKindID("byval")
+			fi.argAttrs = append(fi.argAttrs, tm.ctx.CreateEnumAttribute(argAttrKind, 0))
 		}
 	}
 
diff --git a/irgen/compiler.go b/irgen/compiler.go
index c00a881..acb922e 100644
--- a/irgen/compiler.go
+++ b/irgen/compiler.go
@@ -156,8 +156,8 @@
 func (c *compiler) addCommonFunctionAttrs(fn llvm.Value) {
 	fn.AddTargetDependentFunctionAttr("disable-tail-calls", "true")
 	fn.AddTargetDependentFunctionAttr("split-stack", "")
-	if attr := c.SanitizerAttribute; attr != 0 {
-		fn.AddFunctionAttr(attr)
+	if c.SanitizerAttribute.GetEnumKind() != 0 {
+		fn.AddFunctionAttr(c.SanitizerAttribute)
 	}
 }
 
diff --git a/irgen/maps.go b/irgen/maps.go
index b694bde..6e15396 100644
--- a/irgen/maps.go
+++ b/irgen/maps.go
@@ -39,8 +39,10 @@
 	pk := fr.allocaBuilder.CreateAlloca(llk.Type(), "")
 	fr.builder.CreateStore(llk, pk)
 	valptr := fr.runtime.mapIndex.call(fr, m.value, pk, boolLLVMValue(false))[0]
-	valptr.AddInstrAttribute(2, llvm.NoCaptureAttribute)
-	valptr.AddInstrAttribute(2, llvm.ReadOnlyAttribute)
+	attrkind := llvm.AttributeKindID("nocapture")
+	valptr.AddCallSiteAttribute(2, fr.types.ctx.CreateEnumAttribute(attrkind, 0))
+	attrkind = llvm.AttributeKindID("readonly")
+	valptr.AddCallSiteAttribute(2, fr.types.ctx.CreateEnumAttribute(attrkind, 0))
 	okbit := fr.builder.CreateIsNotNull(valptr, "")
 
 	elemtyp := m.Type().Underlying().(*types.Map).Elem()
@@ -55,8 +57,10 @@
 	pk := fr.allocaBuilder.CreateAlloca(llk.Type(), "")
 	fr.builder.CreateStore(llk, pk)
 	valptr := fr.runtime.mapIndex.call(fr, m.value, pk, boolLLVMValue(true))[0]
-	valptr.AddInstrAttribute(2, llvm.NoCaptureAttribute)
-	valptr.AddInstrAttribute(2, llvm.ReadOnlyAttribute)
+	attrkind := llvm.AttributeKindID("nocapture")
+	valptr.AddCallSiteAttribute(2, fr.types.ctx.CreateEnumAttribute(attrkind, 0))
+	attrkind = llvm.AttributeKindID("readonly")
+	valptr.AddCallSiteAttribute(2, fr.types.ctx.CreateEnumAttribute(attrkind, 0))
 
 	elemtyp := m.Type().Underlying().(*types.Map).Elem()
 	llelemtyp := fr.types.ToLLVM(elemtyp)
diff --git a/irgen/runtime.go b/irgen/runtime.go
index 6e131ce..aa4b7d0 100644
--- a/irgen/runtime.go
+++ b/irgen/runtime.go
@@ -145,6 +145,11 @@
 	ByteSlice := types.NewSlice(types.Typ[types.Byte])
 	IntSlice := types.NewSlice(types.Typ[types.Int])
 
+	AttrKind := llvm.AttributeKindID("nounwind")
+	NoUnwindAttr := module.Context().CreateEnumAttribute(AttrKind, 0)
+	AttrKind = llvm.AttributeKindID("noreturn")
+	NoReturnAttr := module.Context().CreateEnumAttribute(AttrKind, 0)
+
 	for _, rt := range [...]struct {
 		name      string
 		rfi       *runtimeFnInfo
@@ -168,7 +173,7 @@
 			rfi:   &ri.byteArrayToString,
 			args:  []types.Type{UnsafePointer, Int},
 			res:   []types.Type{String},
-			attrs: []llvm.Attribute{llvm.NoUnwindAttribute},
+			attrs: []llvm.Attribute{NoUnwindAttr},
 		},
 		{
 			name: "__go_can_recover",
@@ -314,7 +319,7 @@
 			rfi:   &ri.New,
 			args:  []types.Type{UnsafePointer, Uintptr},
 			res:   []types.Type{UnsafePointer},
-			attrs: []llvm.Attribute{llvm.NoUnwindAttribute},
+			attrs: []llvm.Attribute{NoUnwindAttr},
 		},
 		{
 			name: "__go_new_channel",
@@ -338,7 +343,7 @@
 			name:  "__go_panic",
 			rfi:   &ri.panic,
 			args:  []types.Type{EmptyInterface},
-			attrs: []llvm.Attribute{llvm.NoReturnAttribute},
+			attrs: []llvm.Attribute{NoReturnAttr},
 		},
 		{
 			name: "__go_print_bool",
@@ -417,7 +422,7 @@
 			name:  "__go_runtime_error",
 			rfi:   &ri.runtimeError,
 			args:  []types.Type{Int32},
-			attrs: []llvm.Attribute{llvm.NoReturnAttribute},
+			attrs: []llvm.Attribute{NoReturnAttr},
 		},
 		{
 			name: "runtime.selectdefault",
@@ -474,7 +479,7 @@
 			rfi:   &ri.stringToByteArray,
 			args:  []types.Type{String},
 			res:   []types.Type{ByteSlice},
-			attrs: []llvm.Attribute{llvm.NoUnwindAttribute},
+			attrs: []llvm.Attribute{NoUnwindAttr},
 		},
 		{
 			name: "__go_string_to_int_array",
diff --git a/irgen/ssa.go b/irgen/ssa.go
index 4c7b1a6..aada41c 100644
--- a/irgen/ssa.go
+++ b/irgen/ssa.go
@@ -534,7 +534,9 @@
 func (fr *frame) bridgeRecoverFunc(llfn llvm.Value, fti functionTypeInfo) *frame {
 	// The bridging function must not be inlined, or the return address
 	// may not correspond to the source function.
-	llfn.AddFunctionAttr(llvm.NoInlineAttribute)
+	attrKind := llvm.AttributeKindID("noinline")
+	noInlineAttr := fr.module.Context().CreateEnumAttribute(attrKind, 0)
+	llfn.AddFunctionAttr(noInlineAttr)
 
 	// Call __go_can_recover, passing in the function's return address.
 	entry := llvm.AddBasicBlock(llfn, "entry")