Skip to content

Commit 35318fb

Browse files
author
Tim Foley
authored
More fixes for Falcor IR support (shader-slang#317)
* Fix: try to improve float literal formatting An earlier change switched to using the C++ stdlib to format floats, but I neglected to check that it would correctly print values that happen to be integral with a decimal place (e.g., print `1.0` instead of just `1`). That causes some obscure cases to fail (e.g., when you write `1.0.xxxx` in HLSL, and we print out `1.xxxx`). I've tried to resolve the issue by using the "fixed" output format, but that may also create problems for extremely large or small values (which really need to use scientific notation). However, this at least puts us back where we were before... * Add support for source locations to the IR - Add a `sourceLocation` field to all `IRValue`s - Add some logic to associate locations with operations while lowering (using a slightly "clever" RAII approach) - Make sure that when cloning instructions, we also clone the location - Make the emit logic use the existing support for source locations when emitting code from the IR A nice cleanup to this work would be to have the source locations for IR values not be hyper-specific about both line and column; it is probably enough to just emit on the correct line.
1 parent 8e0e6b6 commit 35318fb

File tree

5 files changed

+88
-2
lines changed

5 files changed

+88
-2
lines changed

source/slang/emit.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ struct EmitVisitor
578578

579579
std::ostringstream stream;
580580
stream.imbue(std::locale::classic());
581+
stream.setf(std::ios::fixed,std::ios::floatfield);
581582
stream.precision(20);
582583
stream << value;
583584

@@ -5322,6 +5323,9 @@ emitDeclImpl(decl, nullptr);
53225323
IRValue* value)
53235324
{
53245325
IRInst* inst = (IRInst*) value;
5326+
5327+
advanceToSourceLocation(inst->sourceLoc);
5328+
53255329
switch(value->op)
53265330
{
53275331
case kIROp_IntLit:
@@ -5617,6 +5621,8 @@ emitDeclImpl(decl, nullptr);
56175621
return;
56185622
}
56195623

5624+
advanceToSourceLocation(inst->sourceLoc);
5625+
56205626
switch(inst->op)
56215627
{
56225628
default:
@@ -5780,6 +5786,8 @@ emitDeclImpl(decl, nullptr);
57805786

57815787
// Now look at the terminator instruction, which will tell us what we need to emit next.
57825788

5789+
advanceToSourceLocation(terminator->sourceLoc);
5790+
57835791
switch (terminator->op)
57845792
{
57855793
default:

source/slang/ir-insts.h

+31
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,8 @@ struct SharedIRBuilder
343343
Dictionary<IRConstantKey, IRConstant*> constantMap;
344344
};
345345

346+
struct IRBuilderSourceLocRAII;
347+
346348
struct IRBuilder
347349
{
348350
// Shared state for all IR builders working on the same module
@@ -366,6 +368,8 @@ struct IRBuilder
366368
IRGlobalValueWithCode* getFunc() { return curFunc; }
367369
IRBlock* getBlock() { return curBlock; }
368370

371+
IRBuilderSourceLocRAII* sourceLocInfo = nullptr;
372+
369373
void addInst(IRBlock* block, IRInst* inst);
370374
void addInst(IRInst* inst);
371375

@@ -559,6 +563,33 @@ struct IRBuilder
559563
IRLayoutDecoration* addLayoutDecoration(IRValue* value, Layout* layout);
560564
};
561565

566+
// Helper to establish the source location that will be used
567+
// by an IRBuilder.
568+
struct IRBuilderSourceLocRAII
569+
{
570+
IRBuilder* builder;
571+
SourceLoc sourceLoc;
572+
IRBuilderSourceLocRAII* next;
573+
574+
IRBuilderSourceLocRAII(
575+
IRBuilder* builder,
576+
SourceLoc sourceLoc)
577+
: builder(builder)
578+
, sourceLoc(sourceLoc)
579+
, next(nullptr)
580+
{
581+
next = builder->sourceLocInfo;
582+
builder->sourceLocInfo = this;
583+
}
584+
585+
~IRBuilderSourceLocRAII()
586+
{
587+
assert(builder->sourceLocInfo == this);
588+
builder->sourceLocInfo = next;
589+
}
590+
};
591+
592+
562593
//
563594

564595
// Interface to IR specialization for use when cloning target-specific

source/slang/ir.cpp

+33-2
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,32 @@ namespace Slang
244244
addInst(parent, inst);
245245
}
246246

247+
static void maybeSetSourceLoc(
248+
IRBuilder* builder,
249+
IRValue* value)
250+
{
251+
if(!builder)
252+
return;
253+
254+
auto sourceLocInfo = builder->sourceLocInfo;
255+
if(!sourceLocInfo)
256+
return;
257+
258+
// Try to find something with usable location info
259+
for(;;)
260+
{
261+
if(sourceLocInfo->sourceLoc.getRaw())
262+
break;
263+
264+
if(!sourceLocInfo->next)
265+
break;
266+
267+
sourceLocInfo = sourceLocInfo->next;
268+
}
269+
270+
value->sourceLoc = sourceLocInfo->sourceLoc;
271+
}
272+
247273
static IRValue* createValueImpl(
248274
IRBuilder* /*builder*/,
249275
UInt size,
@@ -273,7 +299,7 @@ namespace Slang
273299
// arguments *after* the type (which is a mandatory
274300
// argument for all instructions).
275301
static IRInst* createInstImpl(
276-
IRBuilder* /*builder*/,
302+
IRBuilder* builder,
277303
UInt size,
278304
IROp op,
279305
IRType* type,
@@ -291,6 +317,8 @@ namespace Slang
291317

292318
inst->type = type;
293319

320+
maybeSetSourceLoc(builder, inst);
321+
294322
auto operand = inst->getArgs();
295323

296324
for( UInt aa = 0; aa < fixedArgCount; ++aa )
@@ -858,6 +886,7 @@ namespace Slang
858886
this,
859887
kIROp_Func,
860888
nullptr);
889+
maybeSetSourceLoc(this, rsFunc);
861890
addGlobalValue(getModule(), rsFunc);
862891
return rsFunc;
863892
}
@@ -870,6 +899,7 @@ namespace Slang
870899
this,
871900
kIROp_global_var,
872901
ptrType);
902+
maybeSetSourceLoc(this, globalVar);
873903
addGlobalValue(getModule(), globalVar);
874904
return globalVar;
875905
}
@@ -3112,7 +3142,8 @@ namespace Slang
31123142
}
31133143
}
31143144

3115-
// TODO: implement this
3145+
// We will also clone the location here, just because this is a convenient bottleneck
3146+
clonedValue->sourceLoc = originalValue->sourceLoc;
31163147
}
31173148

31183149
struct IRSpecContext : IRSpecContextBase

source/slang/ir.h

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
#include "../core/basic.h"
1111

12+
#include "source-loc.h"
13+
1214
namespace Slang {
1315

1416
class Decl;
@@ -136,6 +138,9 @@ struct IRValue
136138

137139
Type* getType() { return type; }
138140

141+
// Source location information for this value, if any
142+
SourceLoc sourceLoc;
143+
139144
// The linked list of decorations attached to this value
140145
IRDecoration* firstDecoration = nullptr;
141146

source/slang/lower-to-ir.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,7 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
998998
// as the visitor itself.
999999
LoweredValInfo lowerSubExpr(Expr* expr)
10001000
{
1001+
IRBuilderSourceLocRAII sourceLocInfo(getBuilder(), expr->loc);
10011002
return this->dispatch(expr);
10021003
}
10031004

@@ -1667,6 +1668,8 @@ LoweredValInfo lowerLValueExpr(
16671668
IRGenContext* context,
16681669
Expr* expr)
16691670
{
1671+
IRBuilderSourceLocRAII sourceLocInfo(context->irBuilder, expr->loc);
1672+
16701673
LValueExprLoweringVisitor visitor;
16711674
visitor.context = context;
16721675
return visitor.dispatch(expr);
@@ -1676,6 +1679,8 @@ LoweredValInfo lowerRValueExpr(
16761679
IRGenContext* context,
16771680
Expr* expr)
16781681
{
1682+
IRBuilderSourceLocRAII sourceLocInfo(context->irBuilder, expr->loc);
1683+
16791684
RValueExprLoweringVisitor visitor;
16801685
visitor.context = context;
16811686
return visitor.dispatch(expr);
@@ -2380,6 +2385,8 @@ void lowerStmt(
23802385
IRGenContext* context,
23812386
Stmt* stmt)
23822387
{
2388+
IRBuilderSourceLocRAII sourceLocInfo(context->irBuilder, stmt->loc);
2389+
23832390
StmtLoweringVisitor visitor;
23842391
visitor.context = context;
23852392
return visitor.dispatch(stmt);
@@ -2617,6 +2624,8 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
26172624
//
26182625
for (auto decl : declGroup->decls)
26192626
{
2627+
IRBuilderSourceLocRAII sourceLocInfo(context->irBuilder, decl->loc);
2628+
26202629
// Note: I am directly invoking `dispatch` here,
26212630
// instead of `ensureDecl` just to try and
26222631
// make sure that we don't accidentally
@@ -3493,6 +3502,8 @@ LoweredValInfo lowerDecl(
34933502
IRGenContext* context,
34943503
DeclBase* decl)
34953504
{
3505+
IRBuilderSourceLocRAII sourceLocInfo(context->irBuilder, decl->loc);
3506+
34963507
DeclLoweringVisitor visitor;
34973508
visitor.context = context;
34983509
return visitor.dispatch(decl);

0 commit comments

Comments
 (0)