github.com/llir/llvm@v0.3.6/asm/module.go (about)

     1  package asm
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/llir/ll/ast"
     7  	asmenum "github.com/llir/llvm/asm/enum"
     8  	"github.com/llir/llvm/internal/enc"
     9  	"github.com/llir/llvm/ir"
    10  	"github.com/llir/llvm/ir/metadata"
    11  	"github.com/pkg/errors"
    12  )
    13  
    14  // === [ Index AST ] ===========================================================
    15  
    16  // indexTopLevelEntities indexes the AST top-level entities of the given module.
    17  func (gen *generator) indexTopLevelEntities(old *ast.Module) error {
    18  	id := int64(0)
    19  	// 1. Index AST top-level entities.
    20  	for _, entity := range old.TopLevelEntities() {
    21  		switch entity := entity.(type) {
    22  		case *ast.ModuleAsm:
    23  			asm := unquote(entity.Asm().Text())
    24  			gen.m.ModuleAsms = append(gen.m.ModuleAsms, asm)
    25  		case *ast.TypeDef:
    26  			ident := localIdent(entity.Name())
    27  			name := getTypeName(ident)
    28  			if prev, ok := gen.old.typeDefs[name]; ok {
    29  				if _, ok := prev.Typ().(*ast.OpaqueType); !ok {
    30  					return errors.Errorf("type identifier %q already present; prev `%s`, new `%s`", enc.TypeName(name), text(prev), text(entity))
    31  				}
    32  			}
    33  			gen.old.typeDefs[name] = entity
    34  		case *ast.ComdatDef:
    35  			name := comdatName(entity.Name())
    36  			if prev, ok := gen.old.comdatDefs[name]; ok {
    37  				return errors.Errorf("comdat name %q already present; prev `%s`, new `%s`", enc.ComdatName(name), text(prev), text(entity))
    38  			}
    39  			gen.old.comdatDefs[name] = entity
    40  		case *ast.GlobalDecl:
    41  			ident := giveUnnamedIdentID(globalIdent(entity.Name()), &id)
    42  			if prev, ok := gen.old.globals[ident]; ok {
    43  				return errors.Errorf("global identifier %q already present; prev `%s`, new `%s`", ident.Ident(), text(prev), text(entity))
    44  			}
    45  			gen.old.globals[ident] = entity
    46  			gen.old.globalOrder = append(gen.old.globalOrder, ident)
    47  		case *ast.IndirectSymbolDef:
    48  			ident := giveUnnamedIdentID(globalIdent(entity.Name()), &id)
    49  			if prev, ok := gen.old.globals[ident]; ok {
    50  				return errors.Errorf("global identifier %q already present; prev `%s`, new `%s`", ident.Ident(), text(prev), text(entity))
    51  			}
    52  			gen.old.globals[ident] = entity
    53  			gen.old.globalOrder = append(gen.old.globalOrder, ident)
    54  		case *ast.FuncDecl:
    55  			ident := giveUnnamedIdentID(globalIdent(entity.Header().Name()), &id)
    56  			if prev, ok := gen.old.globals[ident]; ok {
    57  				return errors.Errorf("global identifier %q already present; prev `%s`, new `%s`", ident.Ident(), text(prev), text(entity))
    58  			}
    59  			gen.old.globals[ident] = entity
    60  			gen.old.globalOrder = append(gen.old.globalOrder, ident)
    61  		case *ast.FuncDef:
    62  			ident := giveUnnamedIdentID(globalIdent(entity.Header().Name()), &id)
    63  			if prev, ok := gen.old.globals[ident]; ok {
    64  				return errors.Errorf("global identifier %q already present; prev `%s`, new `%s`", ident.Ident(), text(prev), text(entity))
    65  			}
    66  			gen.old.globals[ident] = entity
    67  			gen.old.globalOrder = append(gen.old.globalOrder, ident)
    68  		case *ast.AttrGroupDef:
    69  			id := attrGroupID(entity.ID())
    70  			// Append attribute group definition, and merge at later stage if ID
    71  			// maps to more than one attribute group definition.
    72  			gen.old.attrGroupDefs[id] = append(gen.old.attrGroupDefs[id], entity)
    73  		case *ast.NamedMetadataDef:
    74  			name := metadataName(entity.Name())
    75  			// Multiple named metadata definitions of the same name are allowed.
    76  			// They are merged into a single named metadata definition with the
    77  			// nodes of each definition appended.
    78  			gen.old.namedMetadataDefs[name] = append(gen.old.namedMetadataDefs[name], entity)
    79  		case *ast.MetadataDef:
    80  			id := metadataID(entity.ID())
    81  			if prev, ok := gen.old.metadataDefs[id]; ok {
    82  				return errors.Errorf("metadata ID %q already present; prev `%s`, new `%s`", enc.MetadataID(id), text(prev), text(entity))
    83  			}
    84  			gen.old.metadataDefs[id] = entity
    85  		case *ast.UseListOrder:
    86  			gen.old.useListOrders = append(gen.old.useListOrders, entity)
    87  		case *ast.UseListOrderBB:
    88  			gen.old.useListOrderBBs = append(gen.old.useListOrderBBs, entity)
    89  		default:
    90  			panic(fmt.Errorf("support for AST top-level entity %T not yet implemented", entity))
    91  		}
    92  	}
    93  	return nil
    94  }
    95  
    96  // giveUnnamedIdentID assigns an unused ID to the global identifier if unnamed.
    97  func giveUnnamedIdentID(ident ir.GlobalIdent, id *int64) ir.GlobalIdent {
    98  	if ident.IsUnnamed() {
    99  		// Assign next unused ID to unnamed global identifier.
   100  		ident.SetID(*id)
   101  		*id++
   102  	}
   103  	return ident
   104  }
   105  
   106  // === [ Create and index IR ] =================================================
   107  
   108  // createTopLevelEntities indexes IR top-level identifiers and creates
   109  // scaffolding IR top-level declarations and definitions (without bodies but
   110  // with types) of the given module.
   111  func (gen *generator) createTopLevelEntities() error {
   112  	// 4a. Index top-level identifiers and create scaffolding IR top-level
   113  	//     declarations and definitions (without bodies but with types).
   114  	//
   115  	// Note: the substeps of 4a can be done concurrently.
   116  	//
   117  	// 4a1. Index global identifiers and create scaffolding IR global
   118  	//      declarations and definitions, indirect symbol definitions (aliases
   119  	//      and indirect functions), and function declarations and definitions
   120  	//      (without bodies but with types).
   121  	if err := gen.createGlobalEntities(); err != nil {
   122  		return errors.WithStack(err)
   123  	}
   124  	// 4a2. Index attribute group IDs and create scaffolding IR attribute group
   125  	//      definitions (without bodies).
   126  	gen.createAttrGroupDefs()
   127  	// 4a3. Index metadata names and create scaffolding IR named metadata
   128  	//      definitions (without bodies).
   129  	gen.createNamedMetadataDefs()
   130  	// 4a4. Index metadata IDs and create scaffolding IR metadata definitions
   131  	//      (without bodies).
   132  	gen.createMetadataDefs()
   133  	return nil
   134  }
   135  
   136  // --- [ Attribute group definitions ] -----------------------------------------
   137  
   138  // createAttrGroupDefs indexes IR attribute group IDs and creates scaffolding IR
   139  // attribute group definitions (without bodies) of the given module.
   140  //
   141  // post-condition: gen.new.attrGroupDefs maps from attribute group ID (without
   142  // '#' prefix) to corresponding skeleton IR value.
   143  func (gen *generator) createAttrGroupDefs() {
   144  	// 4a2. Index attribute group IDs and create scaffolding IR attribute group
   145  	//      definitions (without bodies).
   146  	for id := range gen.old.attrGroupDefs {
   147  		new := &ir.AttrGroupDef{ID: id}
   148  		gen.new.attrGroupDefs[id] = new
   149  	}
   150  }
   151  
   152  // --- [ Named metadata definitions ] ------------------------------------------
   153  
   154  // createNamedMetadataDefs indexes IR metadata names and creates scaffolding IR
   155  // named metadata definitions (without bodies) of the given module.
   156  //
   157  // post-condition: gen.new.namedMetadataDefs maps from metadata name (without
   158  // '!' prefix) to corresponding skeleton IR value.
   159  func (gen *generator) createNamedMetadataDefs() {
   160  	// 4a3. Index metadata names and create scaffolding IR named metadata
   161  	//      definitions (without bodies).
   162  	for name := range gen.old.namedMetadataDefs {
   163  		new := &metadata.NamedDef{Name: name}
   164  		gen.new.namedMetadataDefs[name] = new
   165  	}
   166  }
   167  
   168  // --- [ Metadata definitions ] ------------------------------------------------
   169  
   170  // createMetadataDefs indexes IR metadata IDs and creates scaffolding IR
   171  // metadata definitions (without bodies) of the given module.
   172  //
   173  // post-condition: gen.new.metadataDefs maps from metadata ID (without '!'
   174  // prefix) to corresponding skeleton IR value.
   175  func (gen *generator) createMetadataDefs() {
   176  	// 4a4. Index metadata IDs and create scaffolding IR metadata definitions
   177  	//      (without bodies).
   178  	for id, md := range gen.old.metadataDefs {
   179  		new := newMetadataDef(id, md)
   180  		gen.new.metadataDefs[id] = new
   181  	}
   182  }
   183  
   184  // newMetadataDef returns a new IR metadata definition (without body) based on
   185  // the given AST metadata definition.
   186  func newMetadataDef(id int64, old *ast.MetadataDef) metadata.Definition {
   187  	switch oldNode := old.MDNode().(type) {
   188  	case *ast.MDTuple:
   189  		new := &metadata.Tuple{}
   190  		new.SetID(id)
   191  		return new
   192  	case ast.SpecializedMDNode:
   193  		new := newSpecializedMDNode(oldNode)
   194  		new.SetID(id)
   195  		return new
   196  	default:
   197  		panic(fmt.Errorf("support for metadata node %T not yet implemented", oldNode))
   198  	}
   199  }
   200  
   201  // newSpecializedMDNode returns a new IR specialized metadata node (without
   202  // body) based on the given AST specialized metadata node.
   203  func newSpecializedMDNode(old ast.SpecializedMDNode) metadata.SpecializedNode {
   204  	switch old := old.(type) {
   205  	case *ast.DIBasicType:
   206  		return &metadata.DIBasicType{}
   207  	case *ast.DICommonBlock:
   208  		return &metadata.DICommonBlock{}
   209  	case *ast.DICompileUnit:
   210  		return &metadata.DICompileUnit{}
   211  	case *ast.DICompositeType:
   212  		return &metadata.DICompositeType{}
   213  	case *ast.DIDerivedType:
   214  		return &metadata.DIDerivedType{}
   215  	case *ast.DIEnumerator:
   216  		return &metadata.DIEnumerator{}
   217  	case *ast.DIExpression:
   218  		return &metadata.DIExpression{}
   219  	case *ast.DIFile:
   220  		return &metadata.DIFile{}
   221  	case *ast.DIGlobalVariable:
   222  		return &metadata.DIGlobalVariable{}
   223  	case *ast.DIGlobalVariableExpression:
   224  		return &metadata.DIGlobalVariableExpression{}
   225  	case *ast.DIImportedEntity:
   226  		return &metadata.DIImportedEntity{}
   227  	case *ast.DILabel:
   228  		return &metadata.DILabel{}
   229  	case *ast.DILexicalBlock:
   230  		return &metadata.DILexicalBlock{}
   231  	case *ast.DILexicalBlockFile:
   232  		return &metadata.DILexicalBlockFile{}
   233  	case *ast.DILocalVariable:
   234  		return &metadata.DILocalVariable{}
   235  	case *ast.DILocation:
   236  		return &metadata.DILocation{}
   237  	case *ast.DIMacro:
   238  		return &metadata.DIMacro{}
   239  	case *ast.DIMacroFile:
   240  		return &metadata.DIMacroFile{}
   241  	case *ast.DIModule:
   242  		return &metadata.DIModule{}
   243  	case *ast.DINamespace:
   244  		return &metadata.DINamespace{}
   245  	case *ast.DIObjCProperty:
   246  		return &metadata.DIObjCProperty{}
   247  	case *ast.DIStringType:
   248  		return &metadata.DIStringType{}
   249  	case *ast.DISubprogram:
   250  		return &metadata.DISubprogram{}
   251  	case *ast.DISubrange:
   252  		return &metadata.DISubrange{}
   253  	case *ast.DISubroutineType:
   254  		return &metadata.DISubroutineType{}
   255  	case *ast.DITemplateTypeParameter:
   256  		return &metadata.DITemplateTypeParameter{}
   257  	case *ast.DITemplateValueParameter:
   258  		return &metadata.DITemplateValueParameter{}
   259  	case *ast.GenericDINode:
   260  		return &metadata.GenericDINode{}
   261  	default:
   262  		panic(fmt.Errorf("support for %T not yet implemented", old))
   263  	}
   264  }
   265  
   266  // === [ Translate AST to IR ] =================================================
   267  
   268  // --- [ Target definitions ] --------------------------------------------------
   269  
   270  // translateTargetDefs translates the AST target definitions of the given module
   271  // to IR.
   272  func (gen *generator) translateTargetDefs(old *ast.Module) error {
   273  	for _, targetDef := range old.TargetDefs() {
   274  		switch targetDef := targetDef.(type) {
   275  		case *ast.SourceFilename:
   276  			gen.m.SourceFilename = unquote(targetDef.Name().Text())
   277  		case *ast.TargetDataLayout:
   278  			gen.m.DataLayout = unquote(targetDef.DataLayout().Text())
   279  		case *ast.TargetTriple:
   280  			gen.m.TargetTriple = unquote(targetDef.TargetTriple().Text())
   281  		}
   282  	}
   283  	return nil
   284  }
   285  
   286  // --- [ Top-level-entities ] --------------------------------------------------
   287  
   288  // translateTopLevelEntities translates the AST top-level declarations and
   289  // definitions of the given module to IR.
   290  func (gen *generator) translateTopLevelEntities() error {
   291  	// TODO: make concurrent and benchmark difference in walltime.
   292  
   293  	// 4b. Translate AST top-level declarations and definitions to IR.
   294  	//
   295  	// Note: the substeps of 4b can be done concurrently.
   296  	//
   297  	// 4b1. Translate AST global declarations and definitions, alias and IFunc
   298  	//      definitions, and function declarations and definitions to IR.
   299  	if err := gen.translateGlobalEntities(); err != nil {
   300  		return errors.WithStack(err)
   301  	}
   302  	// 4b2. Translate AST attribute group definitions to IR.
   303  	gen.translateAttrGroupDefs()
   304  	// 4b3. Translate AST named metadata definitions to IR.
   305  	if err := gen.translateNamedMetadataDefs(); err != nil {
   306  		return errors.WithStack(err)
   307  	}
   308  	// 4b4. Translate AST metadata definitions to IR.
   309  	return gen.translateMetadataDefs()
   310  }
   311  
   312  // --- [ Comdat definitions ] --------------------------------------------------
   313  
   314  // translateComdatDefs translates the AST comdat definitions of the given module
   315  // to IR.
   316  func (gen *generator) translateComdatDefs() {
   317  	// 3. Translate AST comdat definitions to IR.
   318  	//
   319  	// Note: step 3 and the substeps of 4a can be done concurrently.
   320  	for name, old := range gen.old.comdatDefs {
   321  		new := &ir.ComdatDef{
   322  			Name: name,
   323  			Kind: asmenum.SelectionKindFromString(old.Kind().Text()),
   324  		}
   325  		gen.new.comdatDefs[name] = new
   326  	}
   327  }
   328  
   329  // --- [ Attribute group definitions ] -----------------------------------------
   330  
   331  // translateAttrGroupDefs translates the AST attribute group definitions of the
   332  // given module to IR.
   333  func (gen *generator) translateAttrGroupDefs() {
   334  	// 4b2. Translate AST attribute group definitions to IR.
   335  	for id, old := range gen.old.attrGroupDefs {
   336  		new, ok := gen.new.attrGroupDefs[id]
   337  		if !ok {
   338  			panic(fmt.Errorf("unable to locate attribute group ID %q", enc.AttrGroupID(id)))
   339  		}
   340  		gen.irAttrGroupDef(new, old)
   341  	}
   342  }
   343  
   344  // irAttrGroupDef translates the AST attribute group definitions (one or more)
   345  // to an equivalent IR attribute group definition. Mulriple definitions of the
   346  // same ID are merged into a single attribute group definition.
   347  func (gen *generator) irAttrGroupDef(new *ir.AttrGroupDef, oldDefs []*ast.AttrGroupDef) {
   348  	// present is used to prevent duplicate attributes when merging multiple
   349  	// attribute group definitions.
   350  	present := make(map[string]bool)
   351  	for _, oldDef := range oldDefs {
   352  		for _, oldFuncAttr := range oldDef.FuncAttrs() {
   353  			lit := oldFuncAttr.LlvmNode().Text()
   354  			if present[lit] {
   355  				// skip duplicate attribute.
   356  				continue
   357  			}
   358  			funcAttr := gen.irFuncAttribute(oldFuncAttr)
   359  			new.FuncAttrs = append(new.FuncAttrs, funcAttr)
   360  			present[lit] = true
   361  		}
   362  	}
   363  }
   364  
   365  // --- [ Named metadata definitions ] ------------------------------------------
   366  
   367  // translateNamedMetadataDefs translates the AST named metadata definitions of
   368  // the given module to IR.
   369  func (gen *generator) translateNamedMetadataDefs() error {
   370  	// 4b3. Translate AST named metadata definitions to IR.
   371  	for name, old := range gen.old.namedMetadataDefs {
   372  		new, ok := gen.new.namedMetadataDefs[name]
   373  		if !ok {
   374  			panic(fmt.Errorf("unable to locate metadata name %q", enc.MetadataName(name)))
   375  		}
   376  		for _, oldDef := range old {
   377  			if err := gen.irNamedMetadataDef(new, oldDef); err != nil {
   378  				return errors.WithStack(err)
   379  			}
   380  		}
   381  	}
   382  	return nil
   383  }
   384  
   385  // irNamedMetadataDef translates the given AST named metadata definition to an
   386  // equivalent IR named metadata definition.
   387  func (gen *generator) irNamedMetadataDef(new *metadata.NamedDef, old *ast.NamedMetadataDef) error {
   388  	// Nodes.
   389  	for _, oldNode := range old.MDNodes() {
   390  		node, err := gen.irMetadataNode(oldNode)
   391  		if err != nil {
   392  			return errors.WithStack(err)
   393  		}
   394  		new.Nodes = append(new.Nodes, node)
   395  	}
   396  	return nil
   397  }
   398  
   399  // --- [ Metadata definitions ] ------------------------------------------------
   400  
   401  // translateMetadataDefs translates the AST metadata definitions of the given
   402  // module to IR.
   403  func (gen *generator) translateMetadataDefs() error {
   404  	// 4b4. Translate AST metadata definitions to IR.
   405  	for id, old := range gen.old.metadataDefs {
   406  		new, ok := gen.new.metadataDefs[id]
   407  		if !ok {
   408  			panic(fmt.Errorf("unable to locate metadata ID %q", enc.MetadataID(id)))
   409  		}
   410  		if err := gen.irMetadataDef(new, old); err != nil {
   411  			return errors.WithStack(err)
   412  		}
   413  	}
   414  	return nil
   415  }
   416  
   417  // irMetadataDef translates the given AST metadata definition to an equivalent
   418  // IR metadata definition.
   419  func (gen *generator) irMetadataDef(new metadata.Definition, old *ast.MetadataDef) error {
   420  	// (optional) Distinct.
   421  	if _, ok := old.Distinct(); ok {
   422  		new.SetDistinct(true)
   423  	}
   424  	switch oldNode := old.MDNode().(type) {
   425  	case *ast.MDTuple:
   426  		_, err := gen.irMDTuple(new, oldNode)
   427  		if err != nil {
   428  			return errors.WithStack(err)
   429  		}
   430  	case ast.SpecializedMDNode:
   431  		_, err := gen.irSpecializedMDNode(new, oldNode)
   432  		if err != nil {
   433  			return errors.WithStack(err)
   434  		}
   435  	default:
   436  		panic(fmt.Errorf("support for metadata node %T not yet implemented", old))
   437  	}
   438  	return nil
   439  }
   440  
   441  // --- [ Use-list orders ] -----------------------------------------------------
   442  
   443  // translateUseListOrders translates the AST use-list orders of the given
   444  // module to IR.
   445  func (gen *generator) translateUseListOrders() error {
   446  	// 5. Translate use-list orders.
   447  	if len(gen.old.useListOrders) > 0 {
   448  		gen.m.UseListOrders = make([]*ir.UseListOrder, len(gen.old.useListOrders))
   449  		for i, oldUseListOrder := range gen.old.useListOrders {
   450  			useListOrder, err := gen.irUseListOrder(oldUseListOrder)
   451  			if err != nil {
   452  				return errors.WithStack(err)
   453  			}
   454  			gen.m.UseListOrders[i] = useListOrder
   455  		}
   456  	}
   457  	return nil
   458  }
   459  
   460  // irUseListOrder returns the IR use-list order corresponding to the given AST
   461  // use-list order.
   462  func (gen *generator) irUseListOrder(old *ast.UseListOrder) (*ir.UseListOrder, error) {
   463  	// Value.
   464  	oldVal := old.Val()
   465  	typ, err := gen.irType(oldVal.Typ())
   466  	if err != nil {
   467  		return nil, errors.WithStack(err)
   468  	}
   469  	oldConst, ok := oldVal.Val().(ast.Constant)
   470  	if !ok {
   471  		panic(fmt.Errorf("support for use-list order value %T not yet implemented", oldVal.Val()))
   472  	}
   473  	c, err := gen.irConstant(typ, oldConst)
   474  	if err != nil {
   475  		return nil, errors.WithStack(err)
   476  	}
   477  	// Indices.
   478  	indices := uintSlice(old.Indices())
   479  	useListOrder := &ir.UseListOrder{
   480  		Value:   c,
   481  		Indices: indices,
   482  	}
   483  	return useListOrder, nil
   484  }
   485  
   486  // --- [ Basic block specific use-list orders ] --------------------------------
   487  
   488  // translateUseListOrderBBs translates the AST basic block specific use-list
   489  // orders of the given module to IR.
   490  func (gen *generator) translateUseListOrderBBs() error {
   491  	// 6. Translate basic block specific use-list orders.
   492  	if len(gen.old.useListOrderBBs) > 0 {
   493  		gen.m.UseListOrderBBs = make([]*ir.UseListOrderBB, len(gen.old.useListOrderBBs))
   494  		for i, oldUseListOrderBB := range gen.old.useListOrderBBs {
   495  			useListOrderBB, err := gen.irUseListOrderBB(oldUseListOrderBB)
   496  			if err != nil {
   497  				return errors.WithStack(err)
   498  			}
   499  			gen.m.UseListOrderBBs[i] = useListOrderBB
   500  		}
   501  	}
   502  	return nil
   503  }
   504  
   505  // irUseListOrderBB translates the given AST basic block specific use-list order
   506  // to an equivalent IR basic block specific use-list order.
   507  func (gen *generator) irUseListOrderBB(old *ast.UseListOrderBB) (*ir.UseListOrderBB, error) {
   508  	// Function.
   509  	funcIdent := globalIdent(old.Func())
   510  	v, ok := gen.new.globals[funcIdent]
   511  	if !ok {
   512  		return nil, errors.Errorf("unable to locate global identifier %q", funcIdent.Ident())
   513  	}
   514  	f, ok := v.(*ir.Func)
   515  	if !ok {
   516  		return nil, errors.Errorf("invalid function type of %q; expected *ir.Func, got %T", funcIdent.Ident(), v)
   517  	}
   518  	// Basic block.
   519  	blockIdent := localIdent(old.Block())
   520  	block, err := findBlock(f, blockIdent)
   521  	if err != nil {
   522  		return nil, errors.WithStack(err)
   523  	}
   524  	// Indices.
   525  	indices := uintSlice(old.Indices())
   526  	useListOrderBB := &ir.UseListOrderBB{
   527  		Func:    f,
   528  		Block:   block,
   529  		Indices: indices,
   530  	}
   531  	return useListOrderBB, nil
   532  }