Commit b7946d16 by Andrew Woloszyn

Free memory associated with SPIR-V generation.

parent 863aa667
......@@ -52,6 +52,7 @@
#include "spvIR.h"
#include <algorithm>
#include <memory>
#include <stack>
#include <map>
......@@ -201,11 +202,13 @@ public:
void setBuildPoint(Block* bp) { buildPoint = bp; }
Block* getBuildPoint() const { return buildPoint; }
// Make the main function.
// Make the main function. The returned pointer is only valid
// for the lifetime of this builder.
Function* makeMain();
// Make a shader-style function, and create its entry block if entry is non-zero.
// Return the function, pass back the entry.
// The returned pointer is only valid for the lifetime of this builder.
Function* makeFunctionEntry(Id returnType, const char* name, std::vector<Id>& paramTypes, Block **entry = 0);
// Create a return. An 'implicit' return is one not appearing in the source
......@@ -516,7 +519,7 @@ protected:
void createSelectionMerge(Block* mergeBlock, unsigned int control);
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control);
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
void dumpInstructions(std::vector<unsigned int>&, const std::vector<Instruction*>&) const;
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
struct Loop; // Defined below.
void createBranchToLoopHeaderFromInside(const Loop& loop);
......@@ -535,14 +538,15 @@ protected:
AccessChain accessChain;
// special blocks of instructions for output
std::vector<Instruction*> imports;
std::vector<Instruction*> entryPoints;
std::vector<Instruction*> executionModes;
std::vector<Instruction*> names;
std::vector<Instruction*> lines;
std::vector<Instruction*> decorations;
std::vector<Instruction*> constantsTypesGlobals;
std::vector<Instruction*> externals;
std::vector<std::unique_ptr<Instruction> > imports;
std::vector<std::unique_ptr<Instruction> > entryPoints;
std::vector<std::unique_ptr<Instruction> > executionModes;
std::vector<std::unique_ptr<Instruction> > names;
std::vector<std::unique_ptr<Instruction> > lines;
std::vector<std::unique_ptr<Instruction> > decorations;
std::vector<std::unique_ptr<Instruction> > constantsTypesGlobals;
std::vector<std::unique_ptr<Instruction> > externals;
std::vector<std::unique_ptr<Function> > functions;
// not output, internally used for quick & dirty canonical (unique) creation
std::vector<Instruction*> groupedConstants[OpConstant]; // all types appear before OpConstant
......
......@@ -54,6 +54,7 @@
#include <vector>
#include <iostream>
#include <memory>
#include <assert.h>
namespace spv {
......@@ -155,15 +156,14 @@ public:
Block(Id id, Function& parent);
virtual ~Block()
{
// TODO: free instructions
}
Id getId() { return instructions.front()->getResultId(); }
Function& getParent() const { return parent; }
void addInstruction(Instruction* inst);
void addInstruction(std::unique_ptr<Instruction> inst);
void addPredecessor(Block* pred) { predecessors.push_back(pred); }
void addLocalVariable(Instruction* inst) { localVariables.push_back(inst); }
void addLocalVariable(std::unique_ptr<Instruction> inst) { localVariables.push_back(std::move(inst)); }
int getNumPredecessors() const { return (int)predecessors.size(); }
void setUnreachable() { unreachable = true; }
bool isUnreachable() const { return unreachable; }
......@@ -205,9 +205,9 @@ protected:
// To enforce keeping parent and ownership in sync:
friend Function;
std::vector<Instruction*> instructions;
std::vector<std::unique_ptr<Instruction> > instructions;
std::vector<Block*> predecessors;
std::vector<Instruction*> localVariables;
std::vector<std::unique_ptr<Instruction> > localVariables;
Function& parent;
// track whether this block is known to be uncreachable (not necessarily
......@@ -240,7 +240,7 @@ public:
Module& getParent() const { return parent; }
Block* getEntryBlock() const { return blocks.front(); }
Block* getLastBlock() const { return blocks.back(); }
void addLocalVariable(Instruction* inst);
void addLocalVariable(std::unique_ptr<Instruction> inst);
Id getReturnType() const { return functionInstruction.getTypeId(); }
void dump(std::vector<unsigned int>& out) const
{
......@@ -341,22 +341,24 @@ __inline Function::Function(Id id, Id resultType, Id functionType, Id firstParam
}
}
__inline void Function::addLocalVariable(Instruction* inst)
__inline void Function::addLocalVariable(std::unique_ptr<Instruction> inst)
{
blocks[0]->addLocalVariable(inst);
parent.mapInstruction(inst);
Instruction* raw_instruction = inst.get();
blocks[0]->addLocalVariable(std::move(inst));
parent.mapInstruction(raw_instruction);
}
__inline Block::Block(Id id, Function& parent) : parent(parent), unreachable(false)
{
instructions.push_back(new Instruction(id, NoType, OpLabel));
instructions.push_back(std::unique_ptr<Instruction>(new Instruction(id, NoType, OpLabel)));
}
__inline void Block::addInstruction(Instruction* inst)
__inline void Block::addInstruction(std::unique_ptr<Instruction> inst)
{
instructions.push_back(inst);
if (inst->getResultId())
parent.getParent().mapInstruction(inst);
Instruction* raw_instruction = inst.get();
instructions.push_back(std::move(inst));
if (raw_instruction->getResultId())
parent.getParent().mapInstruction(raw_instruction);
}
}; // end spv namespace
......
......@@ -784,7 +784,9 @@ class TIntermAggregate : public TIntermOperator {
public:
TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
~TIntermAggregate() { delete pragmaTable; }
// Since pragmaTable is allocated with the PoolAllocator, we
// only want to destroy it, not free the associated memory.
~TIntermAggregate() { pragmaTable->~TPragmaTable(); }
virtual TIntermAggregate* getAsAggregate() { return this; }
virtual const TIntermAggregate* getAsAggregate() const { return this; }
virtual void setOperator(TOperator o) { op = o; }
......
......@@ -1613,7 +1613,13 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)
{
assert(!pragmaTable);
pragmaTable = new TPragmaTable();
// We allocate this with the thread-pool allocator because the destructors
// for TIntermNode's are never called. When TIntermNodes are no longer
// needed, the pool allocator destroys all memory at once without
// destruction.
void* memory = GetThreadPoolAllocator().allocate(sizeof(TPragmaTable));
pragmaTable = new(memory) TPragmaTable();
*pragmaTable = pTable;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment