@@ -316,16 +316,14 @@ class SubveqOpRewrite : public ConvertOpToLLVMPattern<quake::SubVeqOp> {
316
316
};
317
317
318
318
// / Lower the quake.reset op to QIR
319
- template <typename ResetOpType>
320
- class ResetRewrite : public ConvertOpToLLVMPattern <ResetOpType> {
319
+ class ResetRewrite : public ConvertOpToLLVMPattern <quake::ResetOp> {
321
320
public:
322
- using Base = ConvertOpToLLVMPattern<ResetOpType>;
323
- using Base::Base;
321
+ using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;
324
322
325
323
LogicalResult
326
- matchAndRewrite (ResetOpType instOp, typename Base:: OpAdaptor adaptor,
324
+ matchAndRewrite (quake::ResetOp instOp, OpAdaptor adaptor,
327
325
ConversionPatternRewriter &rewriter) const override {
328
- auto parentModule = instOp->template getParentOfType <ModuleOp>();
326
+ auto parentModule = instOp->getParentOfType <ModuleOp>();
329
327
auto context = parentModule->getContext ();
330
328
std::string qirQisPrefix (cudaq::opt::QIRQISPrefix);
331
329
std::string instName = instOp->getName ().stripDialect ().str ();
@@ -348,6 +346,37 @@ class ResetRewrite : public ConvertOpToLLVMPattern<ResetOpType> {
348
346
}
349
347
};
350
348
349
+ // / Lower exp_pauli(f64, veq, cc.string) to __quantum__qis__exp_pauli
350
+ class ExpPauliRewrite : public ConvertOpToLLVMPattern <quake::ExpPauliOp> {
351
+ public:
352
+ using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;
353
+
354
+ LogicalResult
355
+ matchAndRewrite (quake::ExpPauliOp instOp, OpAdaptor adaptor,
356
+ ConversionPatternRewriter &rewriter) const override {
357
+ auto loc = instOp->getLoc ();
358
+ auto parentModule = instOp->getParentOfType <ModuleOp>();
359
+ auto *context = rewriter.getContext ();
360
+ std::string qirQisPrefix (cudaq::opt::QIRQISPrefix);
361
+ auto qirFunctionName = qirQisPrefix + " exp_pauli" ;
362
+ FlatSymbolRefAttr symbolRef = cudaq::opt::factory::createLLVMFunctionSymbol (
363
+ qirFunctionName, /* return type=*/ LLVM::LLVMVoidType::get (context),
364
+ {rewriter.getF64Type (), cudaq::opt::getArrayType (context),
365
+ cudaq::opt::factory::getPointerType (context)},
366
+ parentModule);
367
+ SmallVector<Value> operands = adaptor.getOperands ();
368
+ // Make sure to drop any length information from the type of the Pauli word.
369
+ auto pauliWord = operands.back ();
370
+ operands.pop_back ();
371
+ auto castedPauli = rewriter.create <LLVM::BitcastOp>(
372
+ loc, cudaq::opt::factory::getPointerType (context), pauliWord);
373
+ operands.push_back (castedPauli);
374
+ rewriter.replaceOpWithNewOp <LLVM::CallOp>(instOp, TypeRange{}, symbolRef,
375
+ operands);
376
+ return success ();
377
+ }
378
+ };
379
+
351
380
// / Lower single target Quantum ops with no parameter to QIR:
352
381
// / h, x, y, z, s, t
353
382
template <typename OP>
@@ -1310,6 +1339,42 @@ class StdvecSizeOpPattern
1310
1339
}
1311
1340
};
1312
1341
1342
+ class CreateStringLiteralOpPattern
1343
+ : public ConvertOpToLLVMPattern<cudaq::cc::CreateStringLiteralOp> {
1344
+ public:
1345
+ using Base = ConvertOpToLLVMPattern<cudaq::cc::CreateStringLiteralOp>;
1346
+ using Base::Base;
1347
+
1348
+ LogicalResult
1349
+ matchAndRewrite (cudaq::cc::CreateStringLiteralOp stringLiteralOp,
1350
+ OpAdaptor adaptor,
1351
+ ConversionPatternRewriter &rewriter) const override {
1352
+ auto loc = stringLiteralOp.getLoc ();
1353
+ auto parentModule = stringLiteralOp->getParentOfType <ModuleOp>();
1354
+ StringRef stringLiteral = stringLiteralOp.getStringLiteral ();
1355
+
1356
+ // Write to the module body
1357
+ auto insertPoint = rewriter.saveInsertionPoint ();
1358
+ rewriter.setInsertionPointToStart (parentModule.getBody ());
1359
+
1360
+ // Create the register name global
1361
+ auto builder = cudaq::IRBuilder::atBlockEnd (parentModule.getBody ());
1362
+ auto slGlobal =
1363
+ builder.genCStringLiteralAppendNul (loc, parentModule, stringLiteral);
1364
+
1365
+ // Shift back to the function
1366
+ rewriter.restoreInsertionPoint (insertPoint);
1367
+
1368
+ // Get the string address
1369
+ rewriter.replaceOpWithNewOp <LLVM::AddressOfOp>(
1370
+ stringLiteralOp,
1371
+ cudaq::opt::factory::getPointerType (slGlobal.getType ()),
1372
+ slGlobal.getSymName ());
1373
+
1374
+ return success ();
1375
+ }
1376
+ };
1377
+
1313
1378
class StoreOpPattern : public ConvertOpToLLVMPattern <cudaq::cc::StoreOp> {
1314
1379
public:
1315
1380
using Base = ConvertOpToLLVMPattern<cudaq::cc::StoreOp>;
@@ -1420,25 +1485,26 @@ class QuakeToQIRRewrite : public cudaq::opt::QuakeToQIRBase<QuakeToQIRRewrite> {
1420
1485
1421
1486
patterns.insert <GetVeqSizeOpRewrite, MxToMz, MyToMz, ReturnBitRewrite>(
1422
1487
context);
1423
- patterns.insert <
1424
- AllocaOpRewrite, AllocaOpPattern, CallableClosureOpPattern,
1425
- CallableFuncOpPattern, CallCallableOpPattern, CastOpPattern,
1426
- ComputePtrOpPattern, ConcatOpRewrite, DeallocOpRewrite,
1427
- ExtractQubitOpRewrite, ExtractValueOpPattern, FuncToPtrOpPattern,
1428
- InsertValueOpPattern, InstantiateCallableOpPattern, LoadOpPattern,
1429
- OneTargetRewrite<quake::HOp>, OneTargetRewrite<quake::XOp>,
1430
- OneTargetRewrite<quake::YOp>, OneTargetRewrite<quake::ZOp>,
1431
- OneTargetRewrite<quake::SOp>, OneTargetRewrite<quake::TOp>,
1432
- OneTargetOneParamRewrite<quake::R1Op>,
1433
- OneTargetTwoParamRewrite<quake::PhasedRxOp>,
1434
- OneTargetOneParamRewrite<quake::RxOp>,
1435
- OneTargetOneParamRewrite<quake::RyOp>,
1436
- OneTargetOneParamRewrite<quake::RzOp>,
1437
- OneTargetTwoParamRewrite<quake::U2Op>,
1438
- OneTargetTwoParamRewrite<quake::U3Op>, ResetRewrite<quake::ResetOp>,
1439
- StdvecDataOpPattern, StdvecInitOpPattern, StdvecSizeOpPattern,
1440
- StoreOpPattern, SubveqOpRewrite, TwoTargetRewrite<quake::SwapOp>,
1441
- UndefOpPattern>(typeConverter);
1488
+ patterns
1489
+ .insert <AllocaOpRewrite, AllocaOpPattern, CallableClosureOpPattern,
1490
+ CallableFuncOpPattern, CallCallableOpPattern, CastOpPattern,
1491
+ ComputePtrOpPattern, ConcatOpRewrite, DeallocOpRewrite,
1492
+ CreateStringLiteralOpPattern, ExtractQubitOpRewrite,
1493
+ ExtractValueOpPattern, FuncToPtrOpPattern, InsertValueOpPattern,
1494
+ InstantiateCallableOpPattern, LoadOpPattern, ExpPauliRewrite,
1495
+ OneTargetRewrite<quake::HOp>, OneTargetRewrite<quake::XOp>,
1496
+ OneTargetRewrite<quake::YOp>, OneTargetRewrite<quake::ZOp>,
1497
+ OneTargetRewrite<quake::SOp>, OneTargetRewrite<quake::TOp>,
1498
+ OneTargetOneParamRewrite<quake::R1Op>,
1499
+ OneTargetTwoParamRewrite<quake::PhasedRxOp>,
1500
+ OneTargetOneParamRewrite<quake::RxOp>,
1501
+ OneTargetOneParamRewrite<quake::RyOp>,
1502
+ OneTargetOneParamRewrite<quake::RzOp>,
1503
+ OneTargetTwoParamRewrite<quake::U2Op>,
1504
+ OneTargetTwoParamRewrite<quake::U3Op>, ResetRewrite,
1505
+ StdvecDataOpPattern, StdvecInitOpPattern, StdvecSizeOpPattern,
1506
+ StoreOpPattern, SubveqOpRewrite,
1507
+ TwoTargetRewrite<quake::SwapOp>, UndefOpPattern>(typeConverter);
1442
1508
patterns.insert <MeasureRewrite<quake::MzOp>>(typeConverter, measureCounter);
1443
1509
1444
1510
target.addLegalDialect <LLVM::LLVMDialect>();
0 commit comments