From c536bd9e73a4a525771e41b15b209dd1149040cd Mon Sep 17 00:00:00 2001 From: Cong Hou Date: Thu, 10 Sep 2015 23:10:42 +0000 Subject: [PATCH] Pass BranchProbability/BlockMass by value instead of const& as they are small. NFC. llvm-svn: 247357 --- .../llvm/Analysis/BlockFrequencyInfoImpl.h | 28 +++++++++---------- llvm/include/llvm/Support/BlockFrequency.h | 8 +++--- llvm/include/llvm/Support/BranchProbability.h | 9 +++--- llvm/include/llvm/Target/TargetInstrInfo.h | 8 +++--- llvm/lib/CodeGen/IfConversion.cpp | 12 ++++---- llvm/lib/Support/BlockFrequency.cpp | 8 +++--- llvm/lib/Target/AMDGPU/R600InstrInfo.cpp | 6 ++-- llvm/lib/Target/AMDGPU/R600InstrInfo.h | 6 ++-- llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 4 +-- llvm/lib/Target/ARM/ARMBaseInstrInfo.h | 6 ++-- llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp | 6 ++-- llvm/lib/Target/Hexagon/HexagonInstrInfo.h | 6 ++-- llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 2 +- llvm/lib/Target/PowerPC/PPCInstrInfo.h | 10 +++---- llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp | 4 +-- llvm/lib/Target/SystemZ/SystemZInstrInfo.h | 4 +-- .../Support/BranchProbabilityTest.cpp | 2 +- 17 files changed, 64 insertions(+), 65 deletions(-) diff --git a/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h index 6c101a63e128..de53515dbfc6 100644 --- a/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h +++ b/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h @@ -84,7 +84,7 @@ public: /// \brief Add another mass. /// /// Adds another mass, saturating at \a isFull() rather than overflowing. - BlockMass &operator+=(const BlockMass &X) { + BlockMass &operator+=(BlockMass X) { uint64_t Sum = Mass + X.Mass; Mass = Sum < Mass ? UINT64_MAX : Sum; return *this; @@ -94,23 +94,23 @@ public: /// /// Subtracts another mass, saturating at \a isEmpty() rather than /// undeflowing. - BlockMass &operator-=(const BlockMass &X) { + BlockMass &operator-=(BlockMass X) { uint64_t Diff = Mass - X.Mass; Mass = Diff > Mass ? 0 : Diff; return *this; } - BlockMass &operator*=(const BranchProbability &P) { + BlockMass &operator*=(BranchProbability P) { Mass = P.scale(Mass); return *this; } - bool operator==(const BlockMass &X) const { return Mass == X.Mass; } - bool operator!=(const BlockMass &X) const { return Mass != X.Mass; } - bool operator<=(const BlockMass &X) const { return Mass <= X.Mass; } - bool operator>=(const BlockMass &X) const { return Mass >= X.Mass; } - bool operator<(const BlockMass &X) const { return Mass < X.Mass; } - bool operator>(const BlockMass &X) const { return Mass > X.Mass; } + bool operator==(BlockMass X) const { return Mass == X.Mass; } + bool operator!=(BlockMass X) const { return Mass != X.Mass; } + bool operator<=(BlockMass X) const { return Mass <= X.Mass; } + bool operator>=(BlockMass X) const { return Mass >= X.Mass; } + bool operator<(BlockMass X) const { return Mass < X.Mass; } + bool operator>(BlockMass X) const { return Mass > X.Mass; } /// \brief Convert to scaled number. /// @@ -122,20 +122,20 @@ public: raw_ostream &print(raw_ostream &OS) const; }; -inline BlockMass operator+(const BlockMass &L, const BlockMass &R) { +inline BlockMass operator+(BlockMass L, BlockMass R) { return BlockMass(L) += R; } -inline BlockMass operator-(const BlockMass &L, const BlockMass &R) { +inline BlockMass operator-(BlockMass L, BlockMass R) { return BlockMass(L) -= R; } -inline BlockMass operator*(const BlockMass &L, const BranchProbability &R) { +inline BlockMass operator*(BlockMass L, BranchProbability R) { return BlockMass(L) *= R; } -inline BlockMass operator*(const BranchProbability &L, const BlockMass &R) { +inline BlockMass operator*(BranchProbability L, BlockMass R) { return BlockMass(R) *= L; } -inline raw_ostream &operator<<(raw_ostream &OS, const BlockMass &X) { +inline raw_ostream &operator<<(raw_ostream &OS, BlockMass X) { return X.print(OS); } diff --git a/llvm/include/llvm/Support/BlockFrequency.h b/llvm/include/llvm/Support/BlockFrequency.h index 4304a253b287..d43f929e1859 100644 --- a/llvm/include/llvm/Support/BlockFrequency.h +++ b/llvm/include/llvm/Support/BlockFrequency.h @@ -37,13 +37,13 @@ public: /// \brief Multiplies with a branch probability. The computation will never /// overflow. - BlockFrequency &operator*=(const BranchProbability &Prob); - const BlockFrequency operator*(const BranchProbability &Prob) const; + BlockFrequency &operator*=(BranchProbability Prob); + const BlockFrequency operator*(BranchProbability Prob) const; /// \brief Divide by a non-zero branch probability using saturating /// arithmetic. - BlockFrequency &operator/=(const BranchProbability &Prob); - BlockFrequency operator/(const BranchProbability &Prob) const; + BlockFrequency &operator/=(BranchProbability Prob); + BlockFrequency operator/(BranchProbability Prob) const; /// \brief Adds another block frequency using saturating arithmetic. BlockFrequency &operator+=(const BlockFrequency &Freq); diff --git a/llvm/include/llvm/Support/BranchProbability.h b/llvm/include/llvm/Support/BranchProbability.h index a6429dd22a3b..7bef0b699c37 100644 --- a/llvm/include/llvm/Support/BranchProbability.h +++ b/llvm/include/llvm/Support/BranchProbability.h @@ -30,9 +30,10 @@ class BranchProbability { uint32_t D; public: - BranchProbability(uint32_t n, uint32_t d) : N(n), D(d) { - assert(d > 0 && "Denominator cannot be 0!"); - assert(n <= d && "Probability cannot be bigger than 1!"); + BranchProbability(uint32_t Numerator, uint32_t Denominator) + : N(Numerator), D(Denominator) { + assert(D > 0 && "Denominator cannot be 0!"); + assert(N <= D && "Probability cannot be bigger than 1!"); } static BranchProbability getZero() { return BranchProbability(0, 1); } @@ -80,7 +81,7 @@ public: bool operator>=(BranchProbability RHS) const { return !(*this < RHS); } }; -inline raw_ostream &operator<<(raw_ostream &OS, const BranchProbability &Prob) { +inline raw_ostream &operator<<(raw_ostream &OS, BranchProbability Prob) { return Prob.print(OS); } diff --git a/llvm/include/llvm/Target/TargetInstrInfo.h b/llvm/include/llvm/Target/TargetInstrInfo.h index 5ceb37a5dfcc..2077dea498ae 100644 --- a/llvm/include/llvm/Target/TargetInstrInfo.h +++ b/llvm/include/llvm/Target/TargetInstrInfo.h @@ -19,6 +19,7 @@ #include "llvm/CodeGen/MachineCombinerPattern.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/MC/MCInstrInfo.h" +#include "llvm/Support/BranchProbability.h" #include "llvm/Target/TargetRegisterInfo.h" namespace llvm { @@ -38,7 +39,6 @@ class SelectionDAG; class ScheduleDAG; class TargetRegisterClass; class TargetRegisterInfo; -class BranchProbability; class TargetSubtargetInfo; class TargetSchedModel; class DFAPacketizer; @@ -511,7 +511,7 @@ public: virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, - const BranchProbability &Probability) const { + BranchProbability Probability) const { return false; } @@ -526,7 +526,7 @@ public: unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB, unsigned NumFCycles, unsigned ExtraFCycles, - const BranchProbability &Probability) const { + BranchProbability Probability) const { return false; } @@ -538,7 +538,7 @@ public: /// will be properly predicted. virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, - const BranchProbability &Probability) const { + BranchProbability Probability) const { return false; } diff --git a/llvm/lib/CodeGen/IfConversion.cpp b/llvm/lib/CodeGen/IfConversion.cpp index ee0532bfc630..b99e570a4461 100644 --- a/llvm/lib/CodeGen/IfConversion.cpp +++ b/llvm/lib/CodeGen/IfConversion.cpp @@ -190,10 +190,10 @@ namespace { private: bool ReverseBranchCondition(BBInfo &BBI); bool ValidSimple(BBInfo &TrueBBI, unsigned &Dups, - const BranchProbability &Prediction) const; + BranchProbability Prediction) const; bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI, bool FalseBranch, unsigned &Dups, - const BranchProbability &Prediction) const; + BranchProbability Prediction) const; bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI, unsigned &Dups1, unsigned &Dups2) const; void ScanInstructions(BBInfo &BBI); @@ -218,7 +218,7 @@ namespace { bool MeetIfcvtSizeLimit(MachineBasicBlock &BB, unsigned Cycle, unsigned Extra, - const BranchProbability &Prediction) const { + BranchProbability Prediction) const { return Cycle > 0 && TII->isProfitableToIfCvt(BB, Cycle, Extra, Prediction); } @@ -227,7 +227,7 @@ namespace { unsigned TCycle, unsigned TExtra, MachineBasicBlock &FBB, unsigned FCycle, unsigned FExtra, - const BranchProbability &Prediction) const { + BranchProbability Prediction) const { return TCycle > 0 && FCycle > 0 && TII->isProfitableToIfCvt(TBB, TCycle, TExtra, FBB, FCycle, FExtra, Prediction); @@ -474,7 +474,7 @@ static inline MachineBasicBlock *getNextBlock(MachineBasicBlock *BB) { /// number of instructions that the ifcvt would need to duplicate if performed /// in Dups. bool IfConverter::ValidSimple(BBInfo &TrueBBI, unsigned &Dups, - const BranchProbability &Prediction) const { + BranchProbability Prediction) const { Dups = 0; if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone) return false; @@ -501,7 +501,7 @@ bool IfConverter::ValidSimple(BBInfo &TrueBBI, unsigned &Dups, /// if performed in 'Dups'. bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI, bool FalseBranch, unsigned &Dups, - const BranchProbability &Prediction) const { + BranchProbability Prediction) const { Dups = 0; if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone) return false; diff --git a/llvm/lib/Support/BlockFrequency.cpp b/llvm/lib/Support/BlockFrequency.cpp index 6f7e341904b9..e901fe6c2e65 100644 --- a/llvm/lib/Support/BlockFrequency.cpp +++ b/llvm/lib/Support/BlockFrequency.cpp @@ -18,24 +18,24 @@ using namespace llvm; -BlockFrequency &BlockFrequency::operator*=(const BranchProbability &Prob) { +BlockFrequency &BlockFrequency::operator*=(BranchProbability Prob) { Frequency = Prob.scale(Frequency); return *this; } const BlockFrequency -BlockFrequency::operator*(const BranchProbability &Prob) const { +BlockFrequency::operator*(BranchProbability Prob) const { BlockFrequency Freq(Frequency); Freq *= Prob; return Freq; } -BlockFrequency &BlockFrequency::operator/=(const BranchProbability &Prob) { +BlockFrequency &BlockFrequency::operator/=(BranchProbability Prob) { Frequency = Prob.scaleByInverse(Frequency); return *this; } -BlockFrequency BlockFrequency::operator/(const BranchProbability &Prob) const { +BlockFrequency BlockFrequency::operator/(BranchProbability Prob) const { BlockFrequency Freq(Frequency); Freq /= Prob; return Freq; diff --git a/llvm/lib/Target/AMDGPU/R600InstrInfo.cpp b/llvm/lib/Target/AMDGPU/R600InstrInfo.cpp index 855fa9fe45b2..8b6eea17130b 100644 --- a/llvm/lib/Target/AMDGPU/R600InstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/R600InstrInfo.cpp @@ -922,7 +922,7 @@ bool R600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCyles, unsigned ExtraPredCycles, - const BranchProbability &Probability) const{ + BranchProbability Probability) const{ return true; } @@ -933,14 +933,14 @@ R600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB, MachineBasicBlock &FMBB, unsigned NumFCycles, unsigned ExtraFCycles, - const BranchProbability &Probability) const { + BranchProbability Probability) const { return true; } bool R600InstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCyles, - const BranchProbability &Probability) + BranchProbability Probability) const { return true; } diff --git a/llvm/lib/Target/AMDGPU/R600InstrInfo.h b/llvm/lib/Target/AMDGPU/R600InstrInfo.h index dee4c2b9ae31..e7251c31107b 100644 --- a/llvm/lib/Target/AMDGPU/R600InstrInfo.h +++ b/llvm/lib/Target/AMDGPU/R600InstrInfo.h @@ -174,18 +174,18 @@ namespace llvm { bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCyles, - const BranchProbability &Probability) const override; + BranchProbability Probability) const override; bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCyles, unsigned ExtraPredCycles, - const BranchProbability &Probability) const override ; + BranchProbability Probability) const override ; bool isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB, unsigned NumFCycles, unsigned ExtraFCycles, - const BranchProbability &Probability) const override; + BranchProbability Probability) const override; bool DefinesPredicate(MachineInstr *MI, std::vector &Pred) const override; diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index 47a6338f4c31..79ab692c76a4 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1640,7 +1640,7 @@ bool ARMBaseInstrInfo::isSchedulingBoundary(const MachineInstr *MI, bool ARMBaseInstrInfo:: isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, - const BranchProbability &Probability) const { + BranchProbability Probability) const { if (!NumCycles) return false; @@ -1682,7 +1682,7 @@ isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned TCycles, unsigned TExtra, MachineBasicBlock &FMBB, unsigned FCycles, unsigned FExtra, - const BranchProbability &Probability) const { + BranchProbability Probability) const { if (!TCycles || !FCycles) return false; diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h index b4706e348933..80257afdcb9a 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -224,15 +224,15 @@ public: bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, - const BranchProbability &Probability) const override; + BranchProbability Probability) const override; bool isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumT, unsigned ExtraT, MachineBasicBlock &FMBB, unsigned NumF, unsigned ExtraF, - const BranchProbability &Probability) const override; + BranchProbability Probability) const override; bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, - const BranchProbability &Probability) const override { + BranchProbability Probability) const override { return NumCycles == 1; } diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp index 14346a2bda6a..9b12f1482190 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -1063,7 +1063,7 @@ HexagonInstrInfo:: isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, - const BranchProbability &Probability) const { + BranchProbability Probability) const { return true; } @@ -1076,7 +1076,7 @@ isProfitableToIfCvt(MachineBasicBlock &TMBB, MachineBasicBlock &FMBB, unsigned NumFCycles, unsigned ExtraFCycles, - const BranchProbability &Probability) const { + BranchProbability Probability) const { return true; } @@ -1185,7 +1185,7 @@ bool HexagonInstrInfo::ReverseBranchCondition( bool HexagonInstrInfo:: isProfitableToDupForIfCvt(MachineBasicBlock &MBB,unsigned NumInstrs, - const BranchProbability &Probability) const { + BranchProbability Probability) const { return (NumInstrs <= 4); } diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.h b/llvm/lib/Target/Hexagon/HexagonInstrInfo.h index d0b8a4631c1d..0bf43cbee985 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.h +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.h @@ -132,13 +132,13 @@ public: bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, - const BranchProbability &Probability) const override; + BranchProbability Probability) const override; bool isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB, unsigned NumFCycles, unsigned ExtraFCycles, - const BranchProbability &Probability) const override; + BranchProbability Probability) const override; bool isPredicated(const MachineInstr *MI) const override; bool isPredicated(unsigned Opcode) const; @@ -155,7 +155,7 @@ public: ReverseBranchCondition(SmallVectorImpl &Cond) const override; bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, - const BranchProbability &Probability) const override; + BranchProbability Probability) const override; DFAPacketizer * CreateTargetScheduleState(const TargetSubtargetInfo &STI) const override; diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp index 70e223d78ada..d18058fa34ca 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -1474,7 +1474,7 @@ bool PPCInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumT, unsigned ExtraT, MachineBasicBlock &FMBB, unsigned NumF, unsigned ExtraF, - const BranchProbability &Probability) const { + BranchProbability Probability) const { return !(MBBDefinesCTR(TMBB) && MBBDefinesCTR(FMBB)); } diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/llvm/lib/Target/PowerPC/PPCInstrInfo.h index 100860c4d5f4..1d3687ee69d1 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h @@ -215,7 +215,7 @@ public: // profitable to use the predicated branches. bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, - const BranchProbability &Probability) const override { + BranchProbability Probability) const override { return true; } @@ -223,12 +223,10 @@ public: unsigned NumT, unsigned ExtraT, MachineBasicBlock &FMBB, unsigned NumF, unsigned ExtraF, - const BranchProbability &Probability) const override; + BranchProbability Probability) const override; - bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, - unsigned NumCycles, - const BranchProbability - &Probability) const override { + bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, + BranchProbability Probability) const override { return true; } diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp index 5d4a34f7131c..2bac8d5f907a 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -514,7 +514,7 @@ bool SystemZInstrInfo::isPredicable(MachineInstr *MI) const { bool SystemZInstrInfo:: isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, - const BranchProbability &Probability) const { + BranchProbability Probability) const { // For now only convert single instructions. return NumCycles == 1; } @@ -524,7 +524,7 @@ isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumCyclesT, unsigned ExtraPredCyclesT, MachineBasicBlock &FMBB, unsigned NumCyclesF, unsigned ExtraPredCyclesF, - const BranchProbability &Probability) const { + BranchProbability Probability) const { // For now avoid converting mutually-exclusive cases. return false; } diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h index 31c9db209585..d9094ba93658 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h @@ -159,12 +159,12 @@ public: bool isPredicable(MachineInstr *MI) const override; bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, - const BranchProbability &Probability) const override; + BranchProbability Probability) const override; bool isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumCyclesT, unsigned ExtraPredCyclesT, MachineBasicBlock &FMBB, unsigned NumCyclesF, unsigned ExtraPredCyclesF, - const BranchProbability &Probability) const override; + BranchProbability Probability) const override; bool PredicateInstruction(MachineInstr *MI, ArrayRef Pred) const override; void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, diff --git a/llvm/unittests/Support/BranchProbabilityTest.cpp b/llvm/unittests/Support/BranchProbabilityTest.cpp index bbd4d4eba1c0..43bfa849f3a8 100644 --- a/llvm/unittests/Support/BranchProbabilityTest.cpp +++ b/llvm/unittests/Support/BranchProbabilityTest.cpp @@ -14,7 +14,7 @@ using namespace llvm; namespace llvm { -void PrintTo(const BranchProbability &P, ::std::ostream *os) { +void PrintTo(BranchProbability P, ::std::ostream *os) { *os << P.getNumerator() << "/" << P.getDenominator(); } }