@@ -412,35 +412,35 @@ class Importer {
412
412
// / Returns the builtin type equivalent to be used in attributes for the given
413
413
// / LLVM IR dialect type.
414
414
Type getStdTypeForAttr (Type type);
415
- // / Return `value` as an attribute to attach to a GlobalOp.
415
+ // / Returns `value` as an attribute to attach to a GlobalOp.
416
416
Attribute getConstantAsAttr (llvm::Constant *value);
417
- // / Return ` constant` as an MLIR Value. This could either be a ConstantOp, or
418
- // / an expanded sequence of ops in the current function's entry block (for
417
+ // / Converts the LLVM constant to an MLIR value produced by a ConstantOp,
418
+ // / AddressOfOp, NullOp, or to an expanded sequence of operations (for
419
419
// / ConstantExprs or ConstantGEPs).
420
- Value processConstant (llvm::Constant *constant);
420
+ Value convertConstantInPlace (llvm::Constant *constant);
421
+ // / Converts the LLVM constant to an MLIR value using the
422
+ // / `convertConstantInPlace` method and inserts the constant at the start of
423
+ // / the function entry block.
424
+ Value convertConstant (llvm::Constant *constant);
425
+
426
+ // / Set the constant insertion point to the start of the given block.
427
+ void setConstantInsertionPointToStart (Block *block) {
428
+ constantInsertionBlock = block;
429
+ constantInsertionOp = nullptr ;
430
+ }
421
431
422
- // / Builder pointing at where the next Instruction should be generated.
432
+ // / Builder pointing at where the next instruction should be generated.
423
433
OpBuilder builder;
434
+ // / Block to insert the next constant into.
435
+ Block *constantInsertionBlock = nullptr ;
436
+ // / Operation to insert the next constant after.
437
+ Operation *constantInsertionOp = nullptr ;
438
+ // / Operation to insert the next global after.
439
+ Operation *globalInsertionOp = nullptr ;
424
440
// / The current context.
425
441
MLIRContext *context;
426
442
// / The current module being created.
427
443
ModuleOp module ;
428
- // / The entry block of the current function being processed.
429
- Block *currentEntryBlock = nullptr ;
430
-
431
- // / Globals are inserted before the first function, if any.
432
- Block::iterator getGlobalInsertPt () {
433
- Block::iterator it = module .getBody ()->begin ();
434
- Block::iterator endIt = module .getBody ()->end ();
435
- while (it != endIt && !isa<LLVMFuncOp>(it))
436
- ++it;
437
- return it;
438
- }
439
-
440
- // / Functions are always inserted before the module terminator.
441
- Block::iterator getFuncInsertPt () {
442
- return std::prev (module .getBody ()->end ());
443
- }
444
444
445
445
// / Function-local mapping between original and imported block.
446
446
DenseMap<llvm::BasicBlock *, Block *> blockMapping;
@@ -642,7 +642,14 @@ GlobalOp Importer::processGlobal(llvm::GlobalVariable *gv) {
642
642
if (it != globals.end ())
643
643
return it->second ;
644
644
645
- OpBuilder b (module .getBody (), getGlobalInsertPt ());
645
+ // Insert the global after the last one or at the start of the module.
646
+ OpBuilder::InsertionGuard guard (builder);
647
+ if (!globalInsertionOp) {
648
+ builder.setInsertionPointToStart (module .getBody ());
649
+ } else {
650
+ builder.setInsertionPointAfter (globalInsertionOp);
651
+ }
652
+
646
653
Attribute valueAttr;
647
654
if (gv->hasInitializer ())
648
655
valueAttr = getConstantAsAttr (gv->getInitializer ());
@@ -655,20 +662,18 @@ GlobalOp Importer::processGlobal(llvm::GlobalVariable *gv) {
655
662
alignment = align.value ();
656
663
}
657
664
658
- GlobalOp op = b .create <GlobalOp>(
665
+ GlobalOp op = builder .create <GlobalOp>(
659
666
UnknownLoc::get (context), type, gv->isConstant (),
660
667
convertLinkageFromLLVM (gv->getLinkage ()), gv->getName (), valueAttr,
661
668
alignment, /* addr_space=*/ gv->getAddressSpace (),
662
669
/* dso_local=*/ gv->isDSOLocal (), /* thread_local=*/ gv->isThreadLocal ());
670
+ globalInsertionOp = op;
663
671
664
672
if (gv->hasInitializer () && !valueAttr) {
665
- Region &r = op.getInitializerRegion ();
666
- currentEntryBlock = b.createBlock (&r);
667
- b.setInsertionPoint (currentEntryBlock, currentEntryBlock->begin ());
668
- Value v = processConstant (gv->getInitializer ());
669
- if (!v)
670
- return nullptr ;
671
- b.create <ReturnOp>(op.getLoc (), ArrayRef<Value>({v}));
673
+ Block *block = builder.createBlock (&op.getInitializerRegion ());
674
+ setConstantInsertionPointToStart (block);
675
+ Value value = convertConstant (gv->getInitializer ());
676
+ builder.create <ReturnOp>(op.getLoc (), ArrayRef<Value>({value}));
672
677
}
673
678
if (gv->hasAtLeastLocalUnnamedAddr ())
674
679
op.setUnnamedAddr (convertUnnamedAddrFromLLVM (gv->getUnnamedAddr ()));
@@ -678,29 +683,25 @@ GlobalOp Importer::processGlobal(llvm::GlobalVariable *gv) {
678
683
return globals[gv] = op;
679
684
}
680
685
681
- Value Importer::processConstant (llvm::Constant *constant) {
682
- OpBuilder bEntry (currentEntryBlock, currentEntryBlock->begin ());
686
+ Value Importer::convertConstantInPlace (llvm::Constant *constant) {
683
687
if (Attribute attr = getConstantAsAttr (constant)) {
684
688
// These constants can be represented as attributes.
685
- OpBuilder b (currentEntryBlock, currentEntryBlock->begin ());
686
689
Type type = convertType (constant->getType ());
687
690
if (auto symbolRef = attr.dyn_cast <FlatSymbolRefAttr>())
688
- return bEntry .create <AddressOfOp>(UnknownLoc::get (context), type,
689
- symbolRef.getValue ());
690
- return bEntry .create <ConstantOp>(UnknownLoc::get (context), type, attr);
691
+ return builder .create <AddressOfOp>(UnknownLoc::get (context), type,
692
+ symbolRef.getValue ());
693
+ return builder .create <ConstantOp>(UnknownLoc::get (context), type, attr);
691
694
}
692
695
if (auto *cn = dyn_cast<llvm::ConstantPointerNull>(constant)) {
693
696
Type type = convertType (cn->getType ());
694
- return bEntry .create <NullOp>(UnknownLoc::get (context), type);
697
+ return builder .create <NullOp>(UnknownLoc::get (context), type);
695
698
}
696
699
if (auto *gv = dyn_cast<llvm::GlobalVariable>(constant))
697
- return bEntry .create <AddressOfOp>(UnknownLoc::get (context),
698
- processGlobal (gv));
700
+ return builder .create <AddressOfOp>(UnknownLoc::get (context),
701
+ processGlobal (gv));
699
702
700
703
if (auto *ce = dyn_cast<llvm::ConstantExpr>(constant)) {
701
704
llvm::Instruction *i = ce->getAsInstruction ();
702
- OpBuilder::InsertionGuard guard (builder);
703
- builder.setInsertionPoint (currentEntryBlock, currentEntryBlock->begin ());
704
705
if (failed (processInstruction (i)))
705
706
return nullptr ;
706
707
assert (valueMapping.count (i));
@@ -720,7 +721,7 @@ Value Importer::processConstant(llvm::Constant *constant) {
720
721
}
721
722
if (auto *ue = dyn_cast<llvm::UndefValue>(constant)) {
722
723
Type type = convertType (ue->getType ());
723
- return bEntry .create <UndefOp>(UnknownLoc::get (context), type);
724
+ return builder .create <UndefOp>(UnknownLoc::get (context), type);
724
725
}
725
726
726
727
if (isa<llvm::ConstantAggregate>(constant) ||
@@ -747,41 +748,62 @@ Value Importer::processConstant(llvm::Constant *constant) {
747
748
bool useInsertValue = rootType.isa <LLVMArrayType, LLVMStructType>();
748
749
assert ((useInsertValue || LLVM::isCompatibleVectorType (rootType)) &&
749
750
" unrecognized aggregate type" );
750
- Value root = bEntry .create <UndefOp>(UnknownLoc::get (context), rootType);
751
+ Value root = builder .create <UndefOp>(UnknownLoc::get (context), rootType);
751
752
for (unsigned i = 0 ; i < numElements; ++i) {
752
753
llvm::Constant *element = getElement (i);
753
- Value elementValue = processConstant (element);
754
+ Value elementValue = convertConstantInPlace (element);
754
755
if (!elementValue)
755
756
return nullptr ;
756
757
if (useInsertValue) {
757
- root = bEntry .create <InsertValueOp>(UnknownLoc::get (context), root,
758
- elementValue, i);
758
+ root = builder .create <InsertValueOp>(UnknownLoc::get (context), root,
759
+ elementValue, i);
759
760
} else {
760
- Attribute indexAttr = bEntry.getI32IntegerAttr (static_cast <int32_t >(i));
761
- Value indexValue = bEntry.create <ConstantOp>(
762
- UnknownLoc::get (context), bEntry.getI32Type (), indexAttr);
761
+ Attribute indexAttr =
762
+ builder.getI32IntegerAttr (static_cast <int32_t >(i));
763
+ Value indexValue = builder.create <ConstantOp>(
764
+ UnknownLoc::get (context), builder.getI32Type (), indexAttr);
763
765
if (!indexValue)
764
766
return nullptr ;
765
- root = bEntry .create <InsertElementOp>(
767
+ root = builder .create <InsertElementOp>(
766
768
UnknownLoc::get (context), rootType, root, elementValue, indexValue);
767
769
}
768
770
}
769
771
return root;
770
772
}
771
773
772
- emitError (UnknownLoc::get (context))
773
- << " unhandled constant: " << diag (*constant);
774
774
return nullptr ;
775
775
}
776
776
777
+ Value Importer::convertConstant (llvm::Constant *constant) {
778
+ assert (constantInsertionBlock &&
779
+ " expected the constant insertion block to be non-null" );
780
+
781
+ // Insert the constant after the last one or at the start or the entry block.
782
+ OpBuilder::InsertionGuard guard (builder);
783
+ if (!constantInsertionOp) {
784
+ builder.setInsertionPointToStart (constantInsertionBlock);
785
+ } else {
786
+ builder.setInsertionPointAfter (constantInsertionOp);
787
+ }
788
+
789
+ // Convert the constant in-place and update the insertion point if successful.
790
+ if (Value result = convertConstantInPlace (constant)) {
791
+ constantInsertionOp = result.getDefiningOp ();
792
+ return result;
793
+ }
794
+
795
+ llvm::errs () << diag (*constant) << " \n " ;
796
+ llvm_unreachable (" unhandled constant" );
797
+ }
798
+
777
799
Value Importer::processValue (llvm::Value *value) {
778
800
auto it = valueMapping.find (value);
779
801
if (it != valueMapping.end ())
780
802
return it->second ;
781
803
782
- // Process constants such as immediate arguments that have no mapping.
804
+ // Convert constants such as immediate arguments that have no mapping.
783
805
if (auto *c = dyn_cast<llvm::Constant>(value))
784
- return processConstant (c);
806
+ return convertConstant (c);
785
807
786
808
llvm::errs () << diag (*value) << " \n " ;
787
809
llvm_unreachable (" unhandled value" );
@@ -927,7 +949,7 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
927
949
SmallVector<Value, 4 > ops;
928
950
929
951
for (unsigned i = 0 , ie = lpi->getNumClauses (); i < ie; i++)
930
- ops.push_back (processConstant (lpi->getClause (i)));
952
+ ops.push_back (convertConstant (lpi->getClause (i)));
931
953
932
954
Type ty = convertType (lpi->getType ());
933
955
Value res = builder.create <LandingpadOp>(loc, ty, lpi->isCleanup (), ops);
@@ -1034,7 +1056,10 @@ LogicalResult Importer::processFunction(llvm::Function *func) {
1034
1056
bool dsoLocal = func->hasLocalLinkage ();
1035
1057
CConv cconv = convertCConvFromLLVM (func->getCallingConv ());
1036
1058
1037
- builder.setInsertionPoint (module .getBody (), getFuncInsertPt ());
1059
+ // Insert the function at the end of the module.
1060
+ OpBuilder::InsertionGuard guard (builder);
1061
+ builder.setInsertionPoint (module .getBody (), module .getBody ()->end ());
1062
+
1038
1063
LLVMFuncOp funcOp = builder.create <LLVMFuncOp>(
1039
1064
UnknownLoc::get (context), func->getName (), functionType,
1040
1065
convertLinkageFromLLVM (func->getLinkage ()), dsoLocal, cconv);
@@ -1090,7 +1115,6 @@ LogicalResult Importer::processFunction(llvm::Function *func) {
1090
1115
builder.createBlock (&funcOp.getBody (), funcOp.getBody ().end ());
1091
1116
mapBlock (&bb, block);
1092
1117
}
1093
- currentEntryBlock = &funcOp.getFunctionBody ().getBlocks ().front ();
1094
1118
1095
1119
// Add function arguments to the entry block.
1096
1120
for (const auto &it : llvm::enumerate (func->args ())) {
@@ -1103,6 +1127,7 @@ LogicalResult Importer::processFunction(llvm::Function *func) {
1103
1127
// operands defined in a dominating block have a valid mapping to an MLIR
1104
1128
// value once a block is translated.
1105
1129
SetVector<llvm::BasicBlock *> blocks = getTopologicallySortedBlocks (func);
1130
+ setConstantInsertionPointToStart (lookupBlock (blocks.front ()));
1106
1131
for (llvm::BasicBlock *bb : blocks) {
1107
1132
if (failed (processBasicBlock (bb, lookupBlock (bb))))
1108
1133
return failure ();
0 commit comments