summaryrefslogtreecommitdiff
path: root/source/slang/ir-legalize-types.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/ir-legalize-types.cpp')
-rw-r--r--source/slang/ir-legalize-types.cpp152
1 files changed, 82 insertions, 70 deletions
diff --git a/source/slang/ir-legalize-types.cpp b/source/slang/ir-legalize-types.cpp
index 3a0edbb60..4570ecf81 100644
--- a/source/slang/ir-legalize-types.cpp
+++ b/source/slang/ir-legalize-types.cpp
@@ -83,22 +83,23 @@ struct IRTypeLegalizationContext
TypeLegalizationContext* typeLegalizationContext;
// When inserting new globals, put them before this one.
- IRGlobalValue* insertBeforeGlobal = nullptr;
+ IRInst* insertBeforeGlobal = nullptr;
// When inserting new parameters, put them before this one.
IRParam* insertBeforeParam = nullptr;
- Dictionary<IRValue*, LegalVal> mapValToLegalVal;
+ Dictionary<IRInst*, LegalVal> mapValToLegalVal;
IRVar* insertBeforeLocalVar = nullptr;
- // store local var instructions that have been replaced here, so we can free them
+
+ // store instructions that have been replaced here, so we can free them
// when legalization has done
- List<IRInst*> oldLocalVars;
+ List<IRInst*> replacedInstructions;
};
static void registerLegalizedValue(
IRTypeLegalizationContext* context,
- IRValue* irValue,
+ IRInst* irValue,
LegalVal const& legalVal)
{
context->mapValToLegalVal.Add(irValue, legalVal);
@@ -165,7 +166,7 @@ static RefPtr<Type> legalizeSimpleType(
// and turn it into the equivalent legalized value.
static LegalVal legalizeOperand(
IRTypeLegalizationContext* context,
- IRValue* irValue)
+ IRInst* irValue)
{
LegalVal legalVal;
if (context->mapValToLegalVal.TryGetValue(irValue, legalVal))
@@ -178,7 +179,7 @@ static LegalVal legalizeOperand(
}
static void getArgumentValues(
- List<IRValue*> & instArgs,
+ List<IRInst*> & instArgs,
LegalVal val)
{
switch (val.flavor)
@@ -226,9 +227,9 @@ static LegalVal legalizeCall(
auto retType = legalizeType(context, callInst->type);
SLANG_ASSERT(retType.flavor == LegalType::Flavor::simple);
- List<IRValue*> instArgs;
- for (auto i = 1u; i < callInst->argCount; i++)
- getArgumentValues(instArgs, legalizeOperand(context, callInst->getArg(i)));
+ List<IRInst*> instArgs;
+ for (auto i = 1u; i < callInst->getOperandCount(); i++)
+ getArgumentValues(instArgs, legalizeOperand(context, callInst->getOperand(i)));
return LegalVal::simple(context->builder->emitCallInst(
callInst->type,
@@ -479,7 +480,7 @@ static LegalVal legalizeGetElementPtr(
IRTypeLegalizationContext* context,
LegalType type,
LegalVal legalPtrOperand,
- IRValue* indexOperand)
+ IRInst* indexOperand)
{
auto builder = context->builder;
@@ -613,7 +614,7 @@ static LegalVal legalizeInst(
}
}
-RefPtr<VarLayout> findVarLayout(IRValue* value)
+RefPtr<VarLayout> findVarLayout(IRInst* value)
{
if (auto layoutDecoration = value->findDecoration<IRLayoutDecoration>())
return layoutDecoration->layout.As<VarLayout>();
@@ -667,27 +668,66 @@ static LegalVal legalizeLocalVar(
// Remove the old local var.
irLocalVar->removeFromParent();
// add old local var to list
- context->oldLocalVars.Add(irLocalVar);
+ context->replacedInstructions.Add(irLocalVar);
return newVal;
}
break;
}
}
+static LegalVal legalizeParam(
+ IRTypeLegalizationContext* context,
+ IRParam* originalParam)
+{
+ auto legalParamType = legalizeType(context, originalParam->getFullType());
+ if (legalParamType.flavor == LegalType::Flavor::simple)
+ {
+ // Simple case: things were legalized to a simple type,
+ // so we can just use the original parameter as-is.
+ originalParam->type = legalParamType.getSimple();
+ return LegalVal::simple(originalParam);
+ }
+ else
+ {
+ // Complex case: we need to insert zero or more new parameters,
+ // which will replace the old ones.
+
+ context->insertBeforeParam = originalParam;
+
+ auto newVal = declareVars(context, kIROp_Param, legalParamType, nullptr, nullptr, nullptr);
+
+ originalParam->removeFromParent();
+ context->replacedInstructions.Add(originalParam);
+ return newVal;
+ }
+}
+
+
+
static LegalVal legalizeInst(
- IRTypeLegalizationContext* context,
+ IRTypeLegalizationContext* context,
IRInst* inst)
{
- if (inst->op == kIROp_Var)
- return legalizeLocalVar(context, (IRVar*)inst);
+ // Special-case certain operations
+ switch (inst->op)
+ {
+ case kIROp_Var:
+ return legalizeLocalVar(context, cast<IRVar>(inst));
+
+ case kIROp_Param:
+ return legalizeParam(context, cast<IRParam>(inst));
+
+ default:
+ break;
+ }
// Need to legalize all the operands.
- auto argCount = inst->getArgCount();
+ auto argCount = inst->getOperandCount();
List<LegalVal> legalArgs;
bool anyComplex = false;
for (UInt aa = 0; aa < argCount; ++aa)
{
- auto oldArg = inst->getArg(aa);
+ auto oldArg = inst->getOperand(aa);
auto legalArg = legalizeOperand(context, oldArg);
legalArgs.Add(legalArg);
@@ -706,7 +746,7 @@ static LegalVal legalizeInst(
for (UInt aa = 0; aa < argCount; ++aa)
{
auto legalArg = legalArgs[aa];
- inst->setArg(aa, legalArg.getSimple());
+ inst->setOperand(aa, legalArg.getSimple());
}
inst->type = legalType.getSimple();
@@ -720,9 +760,9 @@ static LegalVal legalizeInst(
// We will set up the IR builder so that any new
// instructions generated will be placed after
- // the location of the original instruct.
+ // the location of the original instruction.
auto builder = context->builder;
- builder->curBlock = inst->getParentBlock();
+ builder->curBlock = as<IRBlock>(inst->getParent());
builder->insertBeforeInst = inst->getNextInst();
LegalVal legalVal = legalizeInst(
@@ -795,47 +835,15 @@ static void legalizeFunc(
addParamType(newFuncType, legalParamType);
}
irFunc->type = newFuncType;
- List<LegalVal> paramVals;
- List<IRValue*> oldParams;
// we use this list to store replaced local var insts.
// these old instructions will be freed when we are done.
- context->oldLocalVars.Clear();
+ context->replacedInstructions.Clear();
// Go through the blocks of the function
for (auto bb = irFunc->getFirstBlock(); bb; bb = bb->getNextBlock())
{
- // Legalize the parameters of the block, which may
- // involve increasing the number of parameters
- for (auto pp = bb->getFirstParam(); pp; pp = pp->nextParam)
- {
- auto legalParamType = legalizeType(context, pp->getFullType());
- if (legalParamType.flavor != LegalType::Flavor::simple)
- {
- context->insertBeforeParam = pp;
- context->builder->curBlock = nullptr;
-
- auto paramVal = declareVars(context, kIROp_Param, legalParamType, nullptr, nullptr, nullptr);
- paramVals.Add(paramVal);
- if (pp == bb->getFirstParam())
- {
- bb->firstParam = pp;
- while (bb->firstParam->prevParam)
- bb->firstParam = bb->firstParam->prevParam;
- }
- bb->lastParam = pp->prevParam;
- if (pp->prevParam)
- pp->prevParam->nextParam = pp->nextParam;
- if (pp->nextParam)
- pp->nextParam->prevParam = pp->prevParam;
- auto oldParam = pp;
- oldParams.Add(oldParam);
- registerLegalizedValue(context, oldParam, paramVal);
- }
-
- }
-
- // Now legalize the instructions inside the block
+ // Legalize the instructions inside the block
IRInst* nextInst = nullptr;
for (auto ii = bb->getFirstInst(); ii; ii = nextInst)
{
@@ -847,13 +855,12 @@ static void legalizeFunc(
}
}
- for (auto & op : oldParams)
+
+ // Clean up after any instructions we replaced along the way.
+ for (auto & lv : context->replacedInstructions)
{
- SLANG_ASSERT(op->firstUse == nullptr || op->firstUse->nextUse == nullptr);
- op->deallocate();
- }
- for (auto & lv : context->oldLocalVars)
lv->deallocate();
+ }
}
static LegalVal declareSimpleVar(
@@ -874,7 +881,7 @@ static LegalVal declareSimpleVar(
IRBuilder* builder = context->builder;
- IRValue* irVar = nullptr;
+ IRInst* irVar = nullptr;
LegalVal legalVarVal;
switch (op)
@@ -883,7 +890,7 @@ static LegalVal declareSimpleVar(
{
auto globalVar = builder->createGlobalVar(type);
globalVar->removeFromParent();
- globalVar->insertBefore(context->insertBeforeGlobal, builder->getModule());
+ globalVar->insertBefore(context->insertBeforeGlobal);
// The legalization of a global variable with linkage (one that has
// a mangled name), must also have an exported name, so that code
@@ -924,11 +931,7 @@ static LegalVal declareSimpleVar(
case kIROp_Param:
{
auto param = builder->emitParam(type);
- if (context->insertBeforeParam->prevParam)
- context->insertBeforeParam->prevParam->nextParam = param;
- param->prevParam = context->insertBeforeParam->prevParam;
- param->nextParam = context->insertBeforeParam;
- context->insertBeforeParam->prevParam = param;
+ param->insertBefore(context->insertBeforeParam);
irVar = param;
legalVarVal = LegalVal::simple(irVar);
@@ -1069,7 +1072,7 @@ static void legalizeGlobalVar(
default:
{
- context->insertBeforeGlobal = irGlobalVar->getNextValue();
+ context->insertBeforeGlobal = irGlobalVar->getNextInst();
LegalVarChain* varChain = nullptr;
LegalVarChain varChainStorage;
@@ -1119,7 +1122,7 @@ static void legalizeGlobalConstant(
default:
{
- context->insertBeforeGlobal = irGlobalConstant->getNextValue();
+ context->insertBeforeGlobal = irGlobalConstant->getNextInst();
IRGlobalNameInfo globalNameInfo;
globalNameInfo.globalVar = irGlobalConstant;
@@ -1174,8 +1177,17 @@ static void legalizeTypes(
IRTypeLegalizationContext* context)
{
auto module = context->module;
- for (auto gv = module->getFirstGlobalValue(); gv; gv = gv->getNextValue())
+ IRInst* next = nullptr;
+ for(auto ii = module->getGlobalInsts().getFirst(); ii; ii = next)
{
+ next = ii->getNextInst();
+
+ // TODO: Once we start having global-scope instructions that
+ // aren't `IRGlobalValue`s, we'll actually want to handle those
+ // here too.
+ auto gv = as<IRGlobalValue>(ii);
+ if (!gv)
+ continue;
legalizeGlobalValue(context, gv);
}
}