Skip to content

Commit

Permalink
Merge 2d8bcdd into 31c93cc
Browse files Browse the repository at this point in the history
  • Loading branch information
mewmew committed Jan 2, 2019
2 parents 31c93cc + 2d8bcdd commit 4151275
Show file tree
Hide file tree
Showing 16 changed files with 1,617 additions and 357 deletions.
4 changes: 4 additions & 0 deletions asm/asm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ func TestParseFile(t *testing.T) {
// DIExpression used in named metdata definition.
{path: "testdata/diexpression.ll"},

// Multiple named metadata definitions with the same metadata name should
// be merged into one.
{path: "testdata/multiple_named_metadata_defs.ll"},

// frem constant expression.
{path: "testdata/expr_frem.ll"},

Expand Down
9 changes: 5 additions & 4 deletions asm/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,10 @@ func Example() {
// Aliases: nil,
// IFuncs: nil,
// AttrGroupDefs: nil,
// NamedMetadataDefs: nil,
// MetadataDefs: nil,
// UseListOrders: nil,
// UseListOrderBBs: nil,
// NamedMetadataDefs: {
// },
// MetadataDefs: nil,
// UseListOrders: nil,
// UseListOrderBBs: nil,
// }
}
15 changes: 6 additions & 9 deletions asm/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ type generator struct {
// AST to IR representation.
func newGenerator() *generator {
return &generator{
m: &ir.Module{},
m: ir.NewModule(),
old: oldIndex{
typeDefs: make(map[string]*ast.TypeDef),
comdatDefs: make(map[string]*ast.ComdatDef),
globals: make(map[ir.GlobalIdent]ast.LlvmNode),
attrGroupDefs: make(map[int64]*ast.AttrGroupDef),
namedMetadataDefs: make(map[string]*ast.NamedMetadataDef),
namedMetadataDefs: make(map[string][]*ast.NamedMetadataDef),
metadataDefs: make(map[int64]*ast.MetadataDef),
},
new: newIndex{
Expand All @@ -44,7 +44,7 @@ func newGenerator() *generator {
globals: make(map[ir.GlobalIdent]constant.Constant),
attrGroupDefs: make(map[int64]*ir.AttrGroupDef),
namedMetadataDefs: make(map[string]*metadata.NamedDef),
metadataDefs: make(map[int64]*metadata.Def),
metadataDefs: make(map[int64]metadata.Definition),
},
}
}
Expand Down Expand Up @@ -73,8 +73,8 @@ type oldIndex struct {
// attribute group definition.
attrGroupDefs map[int64]*ast.AttrGroupDef
// namedMetadataDefs maps from metadata name (without '!' prefix) to named
// metadata definition.
namedMetadataDefs map[string]*ast.NamedMetadataDef
// metadata definitions with the same name.
namedMetadataDefs map[string][]*ast.NamedMetadataDef
// metadataDefs maps from metadata ID (without '!' prefix) to metadata
// definition.
metadataDefs map[int64]*ast.MetadataDef
Expand All @@ -89,9 +89,6 @@ type oldIndex struct {
// definitions, indirect symbol definitions, and function declarations and
// definitions in their order of occurrence in the input.
globalOrder []ir.GlobalIdent
// namedMetadataDefOrder records the metadata name of named metadata
// definitions in their order of occurrence in the input.
namedMetadataDefOrder []string
}

// newIndex is an index of IR top-level entities.
Expand Down Expand Up @@ -120,5 +117,5 @@ type newIndex struct {
namedMetadataDefs map[string]*metadata.NamedDef
// metadataDefs maps from metadata ID (without '!' prefix) to metadata
// definition.
metadataDefs map[int64]*metadata.Def
metadataDefs map[int64]metadata.Definition
}
27 changes: 17 additions & 10 deletions asm/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,28 @@ func (gen *generator) irMetadataAttachment(old ast.MetadataAttachment) (*metadat
func (gen *generator) irMDNode(old ast.MDNode) (metadata.MDNode, error) {
switch old := old.(type) {
case *ast.MDTuple:
return gen.irMDTuple(old)
return gen.irMDTuple(nil, old)
case *ast.MetadataID:
return gen.metadataDefFromID(*old)
case ast.SpecializedMDNode:
return gen.irSpecializedMDNode(old)
return gen.irSpecializedMDNode(nil, old)
default:
panic(fmt.Errorf("support for metadata node %T not yet implemented", old))
}
}

// irMDTuple returns the IR metadata tuple corresponding to the given AST
// metadata tuple.
func (gen *generator) irMDTuple(old *ast.MDTuple) (*metadata.Tuple, error) {
tuple := &metadata.Tuple{}
if oldFields := old.MDFields().MDFields(); len(oldFields) > 0 {
// metadata tuple. A new IR metadata tuple correspoding to the AST metadata
// tuple is created if new is nil, otherwise the body of new is populated.
func (gen *generator) irMDTuple(new metadata.Definition, old *ast.MDTuple) (*metadata.Tuple, error) {
tuple, ok := new.(*metadata.Tuple)
if new == nil {
tuple = &metadata.Tuple{}
tuple.SetID(-1) // tuple literal has no ID.
} else if !ok {
panic(fmt.Errorf("invalid IR metadata tuple for AST metadata tuple; expected *metadata.Tuple, got %T", new))
}
if oldFields := old.MDFields(); len(oldFields) > 0 {
tuple.Fields = make([]metadata.Field, len(oldFields))
for i, oldField := range oldFields {
field, err := gen.irMDField(oldField)
Expand Down Expand Up @@ -116,11 +123,11 @@ func (gen *generator) irMetadata(old ast.Metadata) (metadata.Metadata, error) {
s := stringLit(old.Val())
return &metadata.String{Value: s}, nil
case *ast.MDTuple:
return gen.irMDTuple(old)
return gen.irMDTuple(nil, old)
case *ast.MetadataID:
return gen.metadataDefFromID(*old)
case ast.SpecializedMDNode:
return gen.irSpecializedMDNode(old)
return gen.irSpecializedMDNode(nil, old)
default:
panic(fmt.Errorf("support for metadata %T not yet implemented", old))
}
Expand All @@ -133,7 +140,7 @@ func (gen *generator) irMetadataNode(old ast.MetadataNode) (metadata.Node, error
case *ast.MetadataID:
return gen.metadataDefFromID(*old)
case *ast.DIExpression:
return gen.irDIExpression(old)
return gen.irDIExpression(nil, old)
default:
panic(fmt.Errorf("support for metadata node %T not yet implemented", old))
}
Expand All @@ -143,7 +150,7 @@ func (gen *generator) irMetadataNode(old ast.MetadataNode) (metadata.Node, error

// metadataDefFromID returns the IR metadata definition associated with the
// given AST metadata ID.
func (gen *generator) metadataDefFromID(old ast.MetadataID) (*metadata.Def, error) {
func (gen *generator) metadataDefFromID(old ast.MetadataID) (metadata.Definition, error) {
id := metadataID(old)
node, ok := gen.new.metadataDefs[id]
if !ok {
Expand Down
123 changes: 99 additions & 24 deletions asm/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,10 @@ func (gen *generator) indexTopLevelEntities(old *ast.Module) error {
gen.old.attrGroupDefs[id] = entity
case *ast.NamedMetadataDef:
name := metadataName(entity.Name())
if prev, ok := gen.old.namedMetadataDefs[name]; ok {
return errors.Errorf("metadata name %q already present; prev `%s`, new `%s`", enc.MetadataName(name), text(prev), text(entity))
}
gen.old.namedMetadataDefs[name] = entity
gen.old.namedMetadataDefOrder = append(gen.old.namedMetadataDefOrder, name)
// Multiple named metadata definitions of the same name are allowed.
// They are merged into a single named metadata definition with the
// nodes of each definition appended.
gen.old.namedMetadataDefs[name] = append(gen.old.namedMetadataDefs[name], entity)
case *ast.MetadataDef:
id := metadataID(entity.ID())
if prev, ok := gen.old.metadataDefs[id]; ok {
Expand Down Expand Up @@ -172,12 +171,90 @@ func (gen *generator) createNamedMetadataDefs() {
func (gen *generator) createMetadataDefs() {
// 4a4. Index metadata IDs and create scaffolding IR metadata definitions
// (without bodies).
for id := range gen.old.metadataDefs {
new := &metadata.Def{ID: id}
for id, md := range gen.old.metadataDefs {
new := newMetadataDef(id, md)
gen.new.metadataDefs[id] = new
}
}

// newMetadataDef returns a new IR metadata definition (without body) based on
// the given AST metadata definition.
func newMetadataDef(id int64, old *ast.MetadataDef) metadata.Definition {
switch oldNode := old.MDNode().(type) {
case *ast.MDTuple:
new := &metadata.Tuple{}
new.SetID(id)
return new
case ast.SpecializedMDNode:
new := newSpecializedMDNode(oldNode)
new.SetID(id)
return new
default:
panic(fmt.Errorf("support for metadata node %T not yet implemented", oldNode))
}
}

// newSpecializedMDNode returns a new IR specialized metadata node (without
// body) based on the given AST specialized metadata node.
func newSpecializedMDNode(old ast.SpecializedMDNode) metadata.SpecializedNode {
switch old := old.(type) {
case *ast.DIBasicType:
return &metadata.DIBasicType{}
case *ast.DICompileUnit:
return &metadata.DICompileUnit{}
case *ast.DICompositeType:
return &metadata.DICompositeType{}
case *ast.DIDerivedType:
return &metadata.DIDerivedType{}
case *ast.DIEnumerator:
return &metadata.DIEnumerator{}
case *ast.DIExpression:
return &metadata.DIExpression{}
case *ast.DIFile:
return &metadata.DIFile{}
case *ast.DIGlobalVariable:
return &metadata.DIGlobalVariable{}
case *ast.DIGlobalVariableExpression:
return &metadata.DIGlobalVariableExpression{}
case *ast.DIImportedEntity:
return &metadata.DIImportedEntity{}
case *ast.DILabel:
return &metadata.DILabel{}
case *ast.DILexicalBlock:
return &metadata.DILexicalBlock{}
case *ast.DILexicalBlockFile:
return &metadata.DILexicalBlockFile{}
case *ast.DILocalVariable:
return &metadata.DILocalVariable{}
case *ast.DILocation:
return &metadata.DILocation{}
case *ast.DIMacro:
return &metadata.DIMacro{}
case *ast.DIMacroFile:
return &metadata.DIMacroFile{}
case *ast.DIModule:
return &metadata.DIModule{}
case *ast.DINamespace:
return &metadata.DINamespace{}
case *ast.DIObjCProperty:
return &metadata.DIObjCProperty{}
case *ast.DISubprogram:
return &metadata.DISubprogram{}
case *ast.DISubrange:
return &metadata.DISubrange{}
case *ast.DISubroutineType:
return &metadata.DISubroutineType{}
case *ast.DITemplateTypeParameter:
return &metadata.DITemplateTypeParameter{}
case *ast.DITemplateValueParameter:
return &metadata.DITemplateValueParameter{}
case *ast.GenericDINode:
return &metadata.GenericDINode{}
default:
panic(fmt.Errorf("support for %T not yet implemented", old))
}
}

// === [ Translate AST to IR ] =================================================

// translateTopLevelEntities translates the AST top-level declarations and
Expand Down Expand Up @@ -259,8 +336,10 @@ func (gen *generator) translateNamedMetadataDefs() error {
if !ok {
panic(fmt.Errorf("unable to locate metadata name %q", enc.MetadataName(name)))
}
if err := gen.irNamedMetadataDef(new, old); err != nil {
return errors.WithStack(err)
for _, oldDef := range old {
if err := gen.irNamedMetadataDef(new, oldDef); err != nil {
return errors.WithStack(err)
}
}
}
return nil
Expand All @@ -270,15 +349,12 @@ func (gen *generator) translateNamedMetadataDefs() error {
// equivalent IR named metadata definition.
func (gen *generator) irNamedMetadataDef(new *metadata.NamedDef, old *ast.NamedMetadataDef) error {
// Nodes.
if oldNodes := old.MDNodes(); len(oldNodes) > 0 {
new.Nodes = make([]metadata.Node, len(oldNodes))
for i, oldNode := range oldNodes {
node, err := gen.irMetadataNode(oldNode)
if err != nil {
return errors.WithStack(err)
}
new.Nodes[i] = node
for _, oldNode := range old.MDNodes() {
node, err := gen.irMetadataNode(oldNode)
if err != nil {
return errors.WithStack(err)
}
new.Nodes = append(new.Nodes, node)
}
return nil
}
Expand All @@ -303,23 +379,22 @@ func (gen *generator) translateMetadataDefs() error {

// irMetadataDef translates the given AST metadata definition to an equivalent
// IR metadata definition.
func (gen *generator) irMetadataDef(new *metadata.Def, old *ast.MetadataDef) error {
func (gen *generator) irMetadataDef(new metadata.Definition, old *ast.MetadataDef) error {
// (optional) Distinct.
_, new.Distinct = old.Distinct()
// Node.
if _, ok := old.Distinct(); ok {
new.SetDistinct(true)
}
switch oldNode := old.MDNode().(type) {
case *ast.MDTuple:
node, err := gen.irMDTuple(oldNode)
_, err := gen.irMDTuple(new, oldNode)
if err != nil {
return errors.WithStack(err)
}
new.Node = node
case ast.SpecializedMDNode:
node, err := gen.irSpecializedMDNode(oldNode)
_, err := gen.irSpecializedMDNode(new, oldNode)
if err != nil {
return errors.WithStack(err)
}
new.Node = node
default:
panic(fmt.Errorf("support for metadata node %T not yet implemented", old))
}
Expand Down

0 comments on commit 4151275

Please sign in to comment.