Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/*
2
 * Copyright © 2014 Intel Corporation
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice (including the next
12
 * paragraph) shall be included in all copies or substantial portions of the
13
 * Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
 * IN THE SOFTWARE.
22
 */
23
 
24
#include "brw_cfg.h"
25
#include "brw_eu.h"
26
#include "brw_context.h"
27
#include "intel_debug.h"
28
#include "intel_asm_annotation.h"
29
#include "program/prog_print.h"
30
#include "program/prog_instruction.h"
31
#include "main/macros.h"
32
#include "glsl/nir/nir.h"
33
 
34
void
35
dump_assembly(void *assembly, int num_annotations, struct annotation *annotation,
36
              const struct brw_device_info *devinfo,
37
              const struct gl_program *prog)
38
{
39
   const char *last_annotation_string = NULL;
40
   const void *last_annotation_ir = NULL;
41
 
42
   for (int i = 0; i < num_annotations; i++) {
43
      int start_offset = annotation[i].offset;
44
      int end_offset = annotation[i + 1].offset;
45
 
46
      if (annotation[i].block_start) {
47
         fprintf(stderr, "   START B%d", annotation[i].block_start->num);
48
         foreach_list_typed(struct bblock_link, predecessor_link, link,
49
                            &annotation[i].block_start->parents) {
50
            struct bblock_t *predecessor_block = predecessor_link->block;
51
            fprintf(stderr, " <-B%d", predecessor_block->num);
52
         }
53
         fprintf(stderr, "\n");
54
      }
55
 
56
      if (last_annotation_ir != annotation[i].ir) {
57
         last_annotation_ir = annotation[i].ir;
58
         if (last_annotation_ir) {
59
            fprintf(stderr, "   ");
60
            if (prog->nir)
61
               nir_print_instr(annotation[i].ir, stderr);
62
            else if (!prog->Instructions)
63
               fprint_ir(stderr, annotation[i].ir);
64
            else {
65
               const struct prog_instruction *pi =
66
                  (const struct prog_instruction *)annotation[i].ir;
67
               fprintf(stderr, "%d: ",
68
                       (int)(pi - prog->Instructions));
69
               _mesa_fprint_instruction_opt(stderr,
70
                                            pi,
71
                                            0, PROG_PRINT_DEBUG, NULL);
72
            }
73
            fprintf(stderr, "\n");
74
         }
75
      }
76
 
77
      if (last_annotation_string != annotation[i].annotation) {
78
         last_annotation_string = annotation[i].annotation;
79
         if (last_annotation_string)
80
            fprintf(stderr, "   %s\n", last_annotation_string);
81
      }
82
 
83
      brw_disassemble(devinfo, assembly, start_offset, end_offset, stderr);
84
 
85
      if (annotation[i].block_end) {
86
         fprintf(stderr, "   END B%d", annotation[i].block_end->num);
87
         foreach_list_typed(struct bblock_link, successor_link, link,
88
                            &annotation[i].block_end->children) {
89
            struct bblock_t *successor_block = successor_link->block;
90
            fprintf(stderr, " ->B%d", successor_block->num);
91
         }
92
         fprintf(stderr, "\n");
93
      }
94
   }
95
   fprintf(stderr, "\n");
96
}
97
 
98
void annotate(const struct brw_device_info *devinfo,
99
              struct annotation_info *annotation, const struct cfg_t *cfg,
100
              struct backend_instruction *inst, unsigned offset)
101
{
102
   if (annotation->ann_size <= annotation->ann_count) {
103
      int old_size = annotation->ann_size;
104
      annotation->ann_size = MAX2(1024, annotation->ann_size * 2);
105
      annotation->ann = reralloc(annotation->mem_ctx, annotation->ann,
106
                                 struct annotation, annotation->ann_size);
107
      if (!annotation->ann)
108
         return;
109
 
110
      memset(annotation->ann + old_size, 0,
111
             (annotation->ann_size - old_size) * sizeof(struct annotation));
112
   }
113
 
114
   struct annotation *ann = &annotation->ann[annotation->ann_count++];
115
   ann->offset = offset;
116
   if ((INTEL_DEBUG & DEBUG_ANNOTATION) != 0) {
117
      ann->ir = inst->ir;
118
      ann->annotation = inst->annotation;
119
   }
120
 
121
   if (bblock_start(cfg->blocks[annotation->cur_block]) == inst) {
122
      ann->block_start = cfg->blocks[annotation->cur_block];
123
   }
124
 
125
   /* There is no hardware DO instruction on Gen6+, so since DO always
126
    * starts a basic block, we need to set the .block_start of the next
127
    * instruction's annotation with a pointer to the bblock started by
128
    * the DO.
129
    *
130
    * There's also only complication from emitting an annotation without
131
    * a corresponding hardware instruction to disassemble.
132
    */
133
   if (devinfo->gen >= 6 && inst->opcode == BRW_OPCODE_DO) {
134
      annotation->ann_count--;
135
   }
136
 
137
   if (bblock_end(cfg->blocks[annotation->cur_block]) == inst) {
138
      ann->block_end = cfg->blocks[annotation->cur_block];
139
      annotation->cur_block++;
140
   }
141
}
142
 
143
void
144
annotation_finalize(struct annotation_info *annotation,
145
                    unsigned next_inst_offset)
146
{
147
   if (!annotation->ann_count)
148
      return;
149
 
150
   if (annotation->ann_count == annotation->ann_size) {
151
      annotation->ann = reralloc(annotation->mem_ctx, annotation->ann,
152
                                 struct annotation, annotation->ann_size + 1);
153
   }
154
   annotation->ann[annotation->ann_count].offset = next_inst_offset;
155
}