Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(352)

Side by Side Diff: src/IceTargetLowering.h

Issue 1683243003: ARM32 Vector lowering - scalarize select (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Typo fix Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Makefile.standalone ('k') | src/IceTargetLowering.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceTargetLowering.h - Lowering interface -----*- C++ -*-===// 1 //===- subzero/src/IceTargetLowering.h - Lowering interface -----*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 virtual void addProlog(CfgNode *Node) = 0; 318 virtual void addProlog(CfgNode *Node) = 0;
319 virtual void addEpilog(CfgNode *Node) = 0; 319 virtual void addEpilog(CfgNode *Node) = 0;
320 320
321 virtual ~TargetLowering() = default; 321 virtual ~TargetLowering() = default;
322 322
323 private: 323 private:
324 // This control variable is used by AutoBundle (RAII-style bundle 324 // This control variable is used by AutoBundle (RAII-style bundle
325 // locking/unlocking) to prevent nested bundles. 325 // locking/unlocking) to prevent nested bundles.
326 bool AutoBundling = false; 326 bool AutoBundling = false;
327 327
328 /// This indicates whether we are in the genTargetHelperCalls phase, and
329 /// therefore can do things like scalarization.
330 bool GeneratingTargetHelpers = false;
331
328 // _bundle_lock(), and _bundle_unlock(), were made private to force subtargets 332 // _bundle_lock(), and _bundle_unlock(), were made private to force subtargets
329 // to use the AutoBundle helper. 333 // to use the AutoBundle helper.
330 void 334 void
331 _bundle_lock(InstBundleLock::Option BundleOption = InstBundleLock::Opt_None) { 335 _bundle_lock(InstBundleLock::Option BundleOption = InstBundleLock::Opt_None) {
332 Context.insert<InstBundleLock>(BundleOption); 336 Context.insert<InstBundleLock>(BundleOption);
333 } 337 }
334 void _bundle_unlock() { Context.insert<InstBundleUnlock>(); } 338 void _bundle_unlock() { Context.insert<InstBundleUnlock>(); }
335 339
336 protected: 340 protected:
337 /// AutoBundle provides RIAA-style bundling. Sub-targets are expected to use 341 /// AutoBundle provides RIAA-style bundling. Sub-targets are expected to use
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 466
463 void _set_dest_redefined() { Context.getLastInserted()->setDestRedefined(); } 467 void _set_dest_redefined() { Context.getLastInserted()->setDestRedefined(); }
464 468
465 bool shouldOptimizeMemIntrins(); 469 bool shouldOptimizeMemIntrins();
466 470
467 void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest, 471 void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest,
468 Operand *Src0, Operand *Src1); 472 Operand *Src0, Operand *Src1);
469 473
470 /// Generalizes scalarizeArithmetic to support other instruction types. 474 /// Generalizes scalarizeArithmetic to support other instruction types.
471 /// 475 ///
472 /// MakeInstruction is a function-like object with signature 476 /// insertScalarInstruction is a function-like object with signature
473 /// (Variable *Dest, Variable *Src0, Variable *Src1) -> Instr *. 477 /// (Variable *Dest, Variable *Src0, Variable *Src1) -> Instr *.
474 template <typename F> 478 template <typename... Operands,
475 void scalarizeInstruction(Variable *Dest, Operand *Src0, Operand *Src1, 479 typename F = std::function<Inst *(Variable *, Operands *...)>>
476 F &&MakeInstruction) { 480 void scalarizeInstruction(Variable *Dest, F insertScalarInstruction,
481 Operands *... Srcs) {
482 assert(GeneratingTargetHelpers &&
483 "scalarizeInstruction called during incorrect phase");
477 const Type DestTy = Dest->getType(); 484 const Type DestTy = Dest->getType();
478 assert(isVectorType(DestTy)); 485 assert(isVectorType(DestTy));
479 const Type DestElementTy = typeElementType(DestTy); 486 const Type DestElementTy = typeElementType(DestTy);
480 const SizeT NumElements = typeNumElements(DestTy); 487 const SizeT NumElements = typeNumElements(DestTy);
481 const Type Src0ElementTy = typeElementType(Src0->getType());
482 const Type Src1ElementTy = typeElementType(Src1->getType());
483
484 assert(NumElements == typeNumElements(Src0->getType()));
485 assert(NumElements == typeNumElements(Src1->getType()));
486 488
487 Variable *T = Func->makeVariable(DestTy); 489 Variable *T = Func->makeVariable(DestTy);
488 Context.insert<InstFakeDef>(T); 490 Context.insert<InstFakeDef>(T);
491
489 for (SizeT I = 0; I < NumElements; ++I) { 492 for (SizeT I = 0; I < NumElements; ++I) {
490 Constant *Index = Ctx->getConstantInt32(I); 493 auto *Index = Ctx->getConstantInt32(I);
491 494
492 // Extract the next two inputs. 495 auto makeExtractThunk = [this, Index, NumElements](Operand *Src) {
493 Variable *Op0 = Func->makeVariable(Src0ElementTy); 496 return [this, Index, NumElements, Src]() {
494 Context.insert<InstExtractElement>(Op0, Src0, Index); 497 assert(typeNumElements(Src->getType()) == NumElements);
495 Variable *Op1 = Func->makeVariable(Src1ElementTy); 498
496 Context.insert<InstExtractElement>(Op1, Src1, Index); 499 const auto ElementTy = typeElementType(Src->getType());
500 auto *Op = Func->makeVariable(ElementTy);
501 Context.insert<InstExtractElement>(Op, Src, Index);
502 return Op;
503 };
504 };
497 505
498 // Perform the operation as a scalar operation. 506 // Perform the operation as a scalar operation.
499 Variable *Res = Func->makeVariable(DestElementTy); 507 auto *Res = Func->makeVariable(DestElementTy);
500 auto Arith = MakeInstruction(Res, Op0, Op1); 508 auto *Arith = applyToThunkedArgs(insertScalarInstruction, Res,
501 // We might have created an operation that needed a helper call. 509 makeExtractThunk(Srcs)...);
502 genTargetHelperCallFor(Arith); 510 genTargetHelperCallFor(Arith);
503 511
504 // Insert the result into position.
505 Variable *DestT = Func->makeVariable(DestTy); 512 Variable *DestT = Func->makeVariable(DestTy);
506 Context.insert<InstInsertElement>(DestT, T, Res, Index); 513 Context.insert<InstInsertElement>(DestT, T, Res, Index);
507 T = DestT; 514 T = DestT;
508 } 515 }
509 Context.insert<InstAssign>(Dest, T); 516 Context.insert<InstAssign>(Dest, T);
510 } 517 }
511 518
512 template <typename F> 519 // applyToThunkedArgs is used by scalarizeInstruction. Ideally, we would just
513 void scalarizeUnaryInstruction(Variable *Dest, Operand *Src0, 520 // call insertScalarInstruction(Res, Srcs...), but C++ does not specify
514 F &&MakeInstruction) { 521 // evaluation order which means this leads to an unpredictable final
515 const Type DestTy = Dest->getType(); 522 // output. Instead, we wrap each of the Srcs in a thunk and these
516 assert(isVectorType(DestTy)); 523 // applyToThunkedArgs functions apply the thunks in a well defined order so we
517 const Type DestElementTy = typeElementType(DestTy); 524 // still get well-defined output.
518 const SizeT NumElements = typeNumElements(DestTy); 525 Inst *applyToThunkedArgs(
519 const Type Src0ElementTy = typeElementType(Src0->getType()); 526 std::function<Inst *(Variable *, Variable *)> insertScalarInstruction,
527 Variable *Res, std::function<Variable *()> thunk0) {
528 auto *Src0 = thunk0();
529 return insertScalarInstruction(Res, Src0);
530 }
520 531
521 assert(NumElements == typeNumElements(Src0->getType())); 532 Inst *
533 applyToThunkedArgs(std::function<Inst *(Variable *, Variable *, Variable *)>
534 insertScalarInstruction,
535 Variable *Res, std::function<Variable *()> thunk0,
536 std::function<Variable *()> thunk1) {
537 auto *Src0 = thunk0();
538 auto *Src1 = thunk1();
539 return insertScalarInstruction(Res, Src0, Src1);
540 }
522 541
523 Variable *T = Func->makeVariable(DestTy); 542 Inst *applyToThunkedArgs(
524 Context.insert<InstFakeDef>(T); 543 std::function<Inst *(Variable *, Variable *, Variable *, Variable *)>
525 for (SizeT I = 0; I < NumElements; ++I) { 544 insertScalarInstruction,
526 Constant *Index = Ctx->getConstantInt32(I); 545 Variable *Res, std::function<Variable *()> thunk0,
527 546 std::function<Variable *()> thunk1, std::function<Variable *()> thunk2) {
528 // Extract the next two inputs. 547 auto *Src0 = thunk0();
529 Variable *Op0 = Func->makeVariable(Src0ElementTy); 548 auto *Src1 = thunk1();
530 Context.insert<InstExtractElement>(Op0, Src0, Index); 549 auto *Src2 = thunk2();
531 550 return insertScalarInstruction(Res, Src0, Src1, Src2);
532 // Perform the operation as a scalar operation.
533 Variable *Res = Func->makeVariable(DestElementTy);
534 auto Arith = MakeInstruction(Res, Op0);
535 // We might have created an operation that needed a helper call.
536 genTargetHelperCallFor(Arith);
537
538 // Insert the result into position.
539 Variable *DestT = Func->makeVariable(DestTy);
540 Context.insert<InstInsertElement>(DestT, T, Res, Index);
541 T = DestT;
542 }
543 Context.insert<InstAssign>(Dest, T);
544 } 551 }
545 552
546 /// SandboxType enumerates all possible sandboxing strategies that 553 /// SandboxType enumerates all possible sandboxing strategies that
547 enum SandboxType { 554 enum SandboxType {
548 ST_None, 555 ST_None,
549 ST_NaCl, 556 ST_NaCl,
550 ST_Nonsfi, 557 ST_Nonsfi,
551 }; 558 };
552 559
553 static SandboxType determineSandboxTypeFromFlags(const ClFlags &Flags); 560 static SandboxType determineSandboxTypeFromFlags(const ClFlags &Flags);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 virtual void lower() {} 654 virtual void lower() {}
648 655
649 protected: 656 protected:
650 explicit TargetHeaderLowering(GlobalContext *Ctx) : Ctx(Ctx) {} 657 explicit TargetHeaderLowering(GlobalContext *Ctx) : Ctx(Ctx) {}
651 GlobalContext *Ctx; 658 GlobalContext *Ctx;
652 }; 659 };
653 660
654 } // end of namespace Ice 661 } // end of namespace Ice
655 662
656 #endif // SUBZERO_SRC_ICETARGETLOWERING_H 663 #endif // SUBZERO_SRC_ICETARGETLOWERING_H
OLDNEW
« no previous file with comments | « Makefile.standalone ('k') | src/IceTargetLowering.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698