nv50/ir: Build a "symbol" table with the binary offsets of each function.
authorFrancisco Jerez <currojerez@riseup.net>
Fri, 6 Apr 2012 16:50:56 +0000 (18:50 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sat, 14 Apr 2012 19:54:01 +0000 (21:54 +0200)
src/gallium/drivers/nv50/codegen/nv50_ir.cpp
src/gallium/drivers/nv50/codegen/nv50_ir.h
src/gallium/drivers/nv50/codegen/nv50_ir_bb.cpp
src/gallium/drivers/nv50/codegen/nv50_ir_driver.h
src/gallium/drivers/nv50/codegen/nv50_ir_print.cpp
src/gallium/drivers/nv50/codegen/nv50_ir_target.cpp
src/gallium/drivers/nvc0/nvc0_program.c

index 357d6d9e2cc25911d4abe0b469687a9baf665c8e..e3d2417c93fa75c8edef9c3949e4214efb9c496e 100644 (file)
@@ -976,7 +976,7 @@ Program::Program(Type type, Target *arch)
 
    maxGPR = -1;
 
-   main = new Function(this, "MAIN");
+   main = new Function(this, "MAIN", ~0);
    calls.insert(&main->call);
 
    dbgFlags = 0;
index 25e729eb5d409b39eeefbcf952739cf6c7ac8cc1..b582a468b31d969fd4d289d11b2d0cc5bcb00fa8 100644 (file)
@@ -916,7 +916,7 @@ private:
 class Function
 {
 public:
-   Function(Program *, const char *name);
+   Function(Program *, const char *name, uint32_t label);
    ~Function();
 
    static inline Function *get(Graph::Node *node);
@@ -924,6 +924,7 @@ public:
    inline Program *getProgram() const { return prog; }
    inline const char *getName() const { return name; }
    inline int getId() const { return id; }
+   inline uint32_t getLabel() const { return label; }
 
    void print();
    void printLiveIntervals() const;
@@ -968,6 +969,7 @@ private:
    void buildDefSetsPreSSA(BasicBlock *bb, const int seq);
 
 private:
+   uint32_t label;
    int id;
    const char *const name;
    Program *prog;
@@ -1015,6 +1017,8 @@ public:
    const Target *getTarget() const { return target; }
 
 private:
+   void emitSymbolTable(struct nv50_ir_prog_info *);
+
    Type progType;
    Target *target;
 
index 8854247db8bbfeac60b1fcb88bf10a58831764fb..6515ba7e0c9a4e79f8acf2bf9d1542511057553b 100644 (file)
@@ -24,8 +24,9 @@
 
 namespace nv50_ir {
 
-Function::Function(Program *p, const char *fnName)
+Function::Function(Program *p, const char *fnName, uint32_t label)
    : call(this),
+     label(label),
      name(fnName),
      prog(p)
 {
index 84a514091c650bf1d7cf1b1121481edcf4555fb7..ae733a1a924201829b720f772d969c3ada9a0f7a 100644 (file)
@@ -87,6 +87,12 @@ struct nv50_ir_varying
 
 #define NV50_PRIM_PATCHES PIPE_PRIM_MAX
 
+struct nv50_ir_prog_symbol
+{
+   uint32_t label;
+   uint32_t offset;
+};
+
 struct nv50_ir_prog_info
 {
    uint16_t target; /* chipset (0x50, 0x84, 0xc0, ...) */
@@ -105,6 +111,8 @@ struct nv50_ir_prog_info
       uint8_t sourceRep;  /* NV50_PROGRAM_IR */
       const void *source;
       void *relocData;
+      struct nv50_ir_prog_symbol *syms;
+      uint16_t numSyms;
    } bin;
 
    struct nv50_ir_varying sv[PIPE_MAX_SHADER_INPUTS];
index acb5be58801e3801c1f8f97a0b63abf10c93bc65..a831145ef5ddce4e02a8fcd9fb1714fe8f7cdbf6 100644 (file)
@@ -431,7 +431,9 @@ void Instruction::print() const
          PRINT(" %sBUILTIN:%i", colour[TXT_BRA], asFlow()->target.builtin);
       } else
       if (op == OP_CALL && asFlow()->target.fn) {
-         PRINT(" %s%s", colour[TXT_BRA], asFlow()->target.fn->getName());
+         PRINT(" %s%s:%i", colour[TXT_BRA],
+               asFlow()->target.fn->getName(),
+               asFlow()->target.fn->getLabel());
       } else
       if (asFlow()->target.bb)
          PRINT(" %sBB:%i", colour[TXT_BRA], asFlow()->target.bb->getId());
@@ -508,7 +510,7 @@ private:
 bool
 PrintPass::visit(Function *fn)
 {
-   INFO("\n%s:\n", fn->getName());
+   INFO("\n%s:%i\n", fn->getName(), fn->getLabel());
 
    return true;
 }
index c8529a3d3951c8ff083515a61f28b042c0c9cb86..598e0d26384b0b58d9aef69f81fc07b8813c45d0 100644 (file)
@@ -208,6 +208,27 @@ CodeEmitter::prepareEmission(BasicBlock *bb)
    func->binSize += bb->binSize;
 }
 
+void
+Program::emitSymbolTable(struct nv50_ir_prog_info *info)
+{
+   unsigned int n = 0, nMax = allFuncs.getSize();
+
+   info->bin.syms =
+      (struct nv50_ir_prog_symbol *)MALLOC(nMax * sizeof(*info->bin.syms));
+
+   for (ArrayList::Iterator fi = allFuncs.iterator();
+        !fi.end();
+        fi.next(), ++n) {
+      Function *f = (Function *)fi.get();
+      assert(n < nMax);
+
+      info->bin.syms[n].label = f->getLabel();
+      info->bin.syms[n].offset = f->binPos;
+   }
+
+   info->bin.numSyms = n;
+}
+
 bool
 Program::emitBinary(struct nv50_ir_prog_info *info)
 {
@@ -238,6 +259,8 @@ Program::emitBinary(struct nv50_ir_prog_info *info)
    }
    info->bin.relocData = emit->getRelocInfo();
 
+   emitSymbolTable(info);
+
    delete emit;
    return true;
 }
index e867461fb2ecc841997a5517d0d8774a27008d20..50a853abed974f75a1c425cd6f5b87ce0ff377cd 100644 (file)
@@ -568,6 +568,8 @@ nvc0_program_translate(struct nvc0_program *prog)
       NOUVEAU_ERR("shader translation failed: %i\n", ret);
       goto out;
    }
+   if (info->bin.syms) /* we don't need them yet */
+      FREE(info->bin.syms);
 
    prog->code = info->bin.code;
    prog->code_size = info->bin.codeSize;