chandlerc (Chandler Carruth)Administrator
User

Projects

User does not belong to any projects.

User Details

User Since
Jul 7 2012, 2:54 PM (267 w, 2 d)
Roles
Administrator

Recent Activity

Today

chandlerc committed rL311437: Fix a typo in r311435..
Fix a typo in r311435.
Tue, Aug 22, 2:21 AM
chandlerc committed rL311430: Fix a -Wpessimizing-move warning from Clang on this code --.
Fix a -Wpessimizing-move warning from Clang on this code --
Tue, Aug 22, 1:03 AM

Yesterday

chandlerc accepted D36996: [X86] Prevent several calls to ISD::isConstantSplatVector from returning a narrower APInt than the original scalar type.

LGTM, minor nits below, feel free to submit whenever.

Mon, Aug 21, 10:19 PM
chandlerc added inline comments to D36995: [X86] Prevent multiple calls to ISD::isConstantSplatVector from returning a narrower APInt than the original scalar type.
Mon, Aug 21, 8:25 PM
chandlerc added a comment to D36995: [X86] Prevent multiple calls to ISD::isConstantSplatVector from returning a narrower APInt than the original scalar type.

comment on the false parameters to help clarify what is false?

Mon, Aug 21, 8:23 PM
chandlerc accepted D36864: [Profile] backward propagate profile data in jump-threading.

Cool! With the changes below, LGTM.

Mon, Aug 21, 8:00 PM
chandlerc committed rL311318: [x86] Teach the "generic" x86 CPU to avoid patterns that are slow on.
[x86] Teach the "generic" x86 CPU to avoid patterns that are slow on
Mon, Aug 21, 1:46 AM
chandlerc closed D36947: [x86] Teach the "generic" x86 CPU to avoid patterns that are slow on widely used processors. by committing rL311318: [x86] Teach the "generic" x86 CPU to avoid patterns that are slow on.
Mon, Aug 21, 1:46 AM
chandlerc committed rL311317: [x86] Handle more cases where we can re-use an atomic operation's flags.
[x86] Handle more cases where we can re-use an atomic operation's flags
Mon, Aug 21, 1:46 AM
chandlerc closed D36945: [x86] Handle more cases where we can re-use an atomic operation's flags rather than doing a separate comparison. by committing rL311317: [x86] Handle more cases where we can re-use an atomic operation's flags.
Mon, Aug 21, 1:46 AM
chandlerc added a comment to D36947: [x86] Teach the "generic" x86 CPU to avoid patterns that are slow on widely used processors..

This seems really uncontroversial as it essentially just avoids some patterns. Going ahead and landing for now. Happy to revisit or enhance this as desired by others of course.

Mon, Aug 21, 1:37 AM
chandlerc added a comment to D36947: [x86] Teach the "generic" x86 CPU to avoid patterns that are slow on widely used processors..

Seems reasonable to add a comment as to what microarch features we're attempting to target as modern here.

Definitely starting to hit the point where we should verify for amd processors though - I'm not sure how any of the new zen based fare here.

Mon, Aug 21, 12:39 AM

Sun, Aug 20

chandlerc created D36947: [x86] Teach the "generic" x86 CPU to avoid patterns that are slow on widely used processors..
Sun, Aug 20, 9:46 PM
chandlerc created D36945: [x86] Handle more cases where we can re-use an atomic operation's flags rather than doing a separate comparison..
Sun, Aug 20, 7:15 PM
chandlerc committed rL311304: Revert r311077: [LV] Using VPlan ....
Revert r311077: [LV] Using VPlan ...
Sun, Aug 20, 4:20 PM

Sat, Aug 19

chandlerc accepted D36906: Keep Optimization Remark Yaml in NewPM.

LGTM. Andrew already said LGTM, so feel free to land.

Sat, Aug 19, 4:39 PM
chandlerc committed rL311267: [x86] Fix an even stranger corner case where we have multiple levels of.
[x86] Fix an even stranger corner case where we have multiple levels of
Sat, Aug 19, 4:38 PM
chandlerc added a comment to D36858: [x86] Teach the cmov converter to aggressively convert cmovs with memory operands into control flow..

There is still an issue with this implementation, here another reproducer:

target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-unknown"

define i32 @bar(i32* %a, i32* %b, i32* %c, i32 %n1, i32 %n2, i32 %d) #0 {
entry:
  %cmp = icmp sgt i32 %n1, %n2
  %s1 = select i1 %cmp, i32* %a, i32* %b
  %s = select i1 %cmp, i32* %c, i32* %s1
  %p = getelementptr inbounds i32, i32* %s, i64 1
  %load = load i32, i32* %p, align 4
  %res = select i1 %cmp, i32 %d, i32 %load
  
  ret i32 %res
}

attributes #0 = {"target-cpu"="skylake"}
Sat, Aug 19, 4:38 PM
chandlerc requested changes to D36906: Keep Optimization Remark Yaml in NewPM.
Sat, Aug 19, 1:42 AM
chandlerc added a comment to D36896: [TargetTransformInfo] Call target getMemoryOpCost for LoadInst from getUserCost.

This will change *lots* of different things from the vectorizer to the inliner.

Sat, Aug 19, 12:39 AM

Fri, Aug 18

chandlerc committed rL311229: [Inliner] Fix a nasty bug when inlining a non-recursive trace of.
[Inliner] Fix a nasty bug when inlining a non-recursive trace of
Fri, Aug 18, 11:57 PM
chandlerc committed rL311228: [Inliner] Clean up a test case a bit to make it more clear what is being.
[Inliner] Clean up a test case a bit to make it more clear what is being
Fri, Aug 18, 11:07 PM
chandlerc committed rL311227: [SLP] Fix an unused variable warning in non-asserts builds..
[SLP] Fix an unused variable warning in non-asserts builds.
Fri, Aug 18, 10:09 PM
chandlerc committed rL311226: [x86] Teach the cmov converter to aggressively convert cmovs with memory.
[x86] Teach the cmov converter to aggressively convert cmovs with memory
Fri, Aug 18, 10:04 PM
chandlerc closed D36858: [x86] Teach the cmov converter to aggressively convert cmovs with memory operands into control flow. by committing rL311226: [x86] Teach the cmov converter to aggressively convert cmovs with memory.
Fri, Aug 18, 10:04 PM
chandlerc committed rL311225: [x86] Refactor the CMOV conversion pass to be more flexible..
[x86] Refactor the CMOV conversion pass to be more flexible.
Fri, Aug 18, 9:29 PM
chandlerc closed D36783: [x86] Refactor the CMOV conversion pass to be more flexible. by committing rL311225: [x86] Refactor the CMOV conversion pass to be more flexible..
Fri, Aug 18, 9:29 PM
chandlerc added a comment to D36858: [x86] Teach the cmov converter to aggressively convert cmovs with memory operands into control flow..

Ok, review comments addressed, tests added (after winning several battles with the register allocator to make interesting cmov groups).

Fri, Aug 18, 6:07 PM
chandlerc updated the diff for D36858: [x86] Teach the cmov converter to aggressively convert cmovs with memory operands into control flow..

Update with more comprehensive testing and a bug fix mentioned in code review
(as well as the suggested test and an even more exciting test case).

Fri, Aug 18, 6:02 PM
chandlerc accepted D36864: [Profile] backward propagate profile data in jump-threading.

Awesome. LGTM with the minor things below addressed. Let me know if any of this isn't make sense.

Fri, Aug 18, 2:50 PM
chandlerc added a comment to D36858: [x86] Teach the cmov converter to aggressively convert cmovs with memory operands into control flow..

While I'm writing the fix, and since it is already late in your TZ -- any other concerns before I land this?

Fri, Aug 18, 9:57 AM
chandlerc added a comment to D36858: [x86] Teach the cmov converter to aggressively convert cmovs with memory operands into control flow..

Thanks Chandler for preparing the patch, the implementation looks elegant, however, it overlooked a case where the memory registers are a result of a previous CMOV instructions.

Fri, Aug 18, 9:55 AM
chandlerc added a comment to D36864: [Profile] backward propagate profile data in jump-threading.

Really, really nice find here. A bunch of comments below, but they're all pretty minor on the whole.

Fri, Aug 18, 1:40 AM
chandlerc added a comment to D36858: [x86] Teach the cmov converter to aggressively convert cmovs with memory operands into control flow..

I've run this across SPEC CPU 2006 and the LLVM test suite on my Haswell system.

Fri, Aug 18, 1:21 AM

Thu, Aug 17

chandlerc created D36858: [x86] Teach the cmov converter to aggressively convert cmovs with memory operands into control flow..
Thu, Aug 17, 7:02 PM
chandlerc added a dependent revision for D36783: [x86] Refactor the CMOV conversion pass to be more flexible.: D36858: [x86] Teach the cmov converter to aggressively convert cmovs with memory operands into control flow..
Thu, Aug 17, 7:02 PM
chandlerc added a comment to D36783: [x86] Refactor the CMOV conversion pass to be more flexible..

Thanks for the review, updated!

Thu, Aug 17, 7:00 PM
chandlerc updated the diff for D36783: [x86] Refactor the CMOV conversion pass to be more flexible..

Improve comments based on code review.

Thu, Aug 17, 7:00 PM

Wed, Aug 16

chandlerc added a comment to D35788: [DAGCombiner] Extending pattern detection for vector shuffle..

Folks, please consider using utils/shuffle_fuzz.py or some other fuzz testing device. The number of times this lands and gets reverted is becoming fairly disruptive.

Wed, Aug 16, 2:36 PM
chandlerc updated subscribers of D34396: Adding code padding for performance stability - first policy (BranchesWithSameTargetAvoidancePolicy).

Adding folks here with a strong interest in this. =]

Wed, Aug 16, 1:28 PM
chandlerc updated subscribers of D34393: Adding code padding for performance stability - infrastructure.

Adding folks here with a strong interest in this. =]

Wed, Aug 16, 1:27 PM
chandlerc created D36783: [x86] Refactor the CMOV conversion pass to be more flexible..
Wed, Aug 16, 12:45 AM
chandlerc committed rL310994: Fix a UBSan failure where this boolean was copied when uninitialized..
Fix a UBSan failure where this boolean was copied when uninitialized.
Wed, Aug 16, 12:24 AM

Tue, Aug 15

chandlerc added a comment to D36388: [X86][SandyBridge] Additional updates to the SNB instructions scheduling information .

FYI, this shows a *very* substantial regression (>20% for some file formats and operations) for us on a compression benchmark. It is similar to the open source Snappy code. The open source Snappy benchmark regresses as well, but less severe: https://github.com/google/snappy

Tue, Aug 15, 11:35 AM

Mon, Aug 14

chandlerc added inline comments to D36722: [InlineCost] Simplify the cold attribute handling in inline-cost..
Mon, Aug 14, 6:43 PM
chandlerc added a comment to D36726: [Inliner] Teach the inliner to propagate attributes that have specific effects on inlining thresholds when we happen to inline into the entry (extended) basic block..

I will provide more comments on propagating the inline hint later. However, I do think it is wrong to propagate the cold attribute in inliner -- there should be already an inter-procedural attribute propagation pass that does this.

Mon, Aug 14, 6:31 PM
chandlerc added inline comments to D36722: [InlineCost] Simplify the cold attribute handling in inline-cost..
Mon, Aug 14, 6:29 PM
chandlerc added inline comments to D36722: [InlineCost] Simplify the cold attribute handling in inline-cost..
Mon, Aug 14, 6:20 PM
chandlerc added a dependent revision for D36722: [InlineCost] Simplify the cold attribute handling in inline-cost.: D36726: [Inliner] Teach the inliner to propagate attributes that have specific effects on inlining thresholds when we happen to inline into the entry (extended) basic block..
Mon, Aug 14, 6:06 PM
chandlerc created D36726: [Inliner] Teach the inliner to propagate attributes that have specific effects on inlining thresholds when we happen to inline into the entry (extended) basic block..
Mon, Aug 14, 6:06 PM
chandlerc added inline comments to D36722: [InlineCost] Simplify the cold attribute handling in inline-cost..
Mon, Aug 14, 5:36 PM
chandlerc created D36722: [InlineCost] Simplify the cold attribute handling in inline-cost..
Mon, Aug 14, 5:08 PM
chandlerc committed rL310888: [InlineCost] Refactor the checks for different analyses to be a bit more.
[InlineCost] Refactor the checks for different analyses to be a bit more
Mon, Aug 14, 2:26 PM
chandlerc closed D36710: [InlineCost] NFC - refactor the checks for different analyses to be a bit more localized to the code that uses those analyses. by committing rL310888: [InlineCost] Refactor the checks for different analyses to be a bit more.
Mon, Aug 14, 2:25 PM
chandlerc added a comment to D36710: [InlineCost] NFC - refactor the checks for different analyses to be a bit more localized to the code that uses those analyses..

LGTM

Mon, Aug 14, 2:20 PM
chandlerc created D36710: [InlineCost] NFC - refactor the checks for different analyses to be a bit more localized to the code that uses those analyses..
Mon, Aug 14, 1:50 PM
chandlerc committed rL310816: [ValueTracking] Revert r310583 which enabled functionality that still is.
[ValueTracking] Revert r310583 which enabled functionality that still is
Mon, Aug 14, 12:04 AM

Sun, Aug 13

chandlerc committed rL310809: [PowerPC] Revert r310346 (and followups r310356 & r310424) which.
[PowerPC] Revert r310346 (and followups r310356 & r310424) which
Sun, Aug 13, 8:44 PM
chandlerc accepted D36655: Move SampleProfileLoader pass before all simplification passes..

The code change LGTM.

Sun, Aug 13, 4:00 PM
chandlerc added inline comments to D36655: Move SampleProfileLoader pass before all simplification passes..
Sun, Aug 13, 1:57 PM

Thu, Aug 10

chandlerc committed rL310695: [PM] Switch the CGSCC debug messages to use the standard LLVM debug.
[PM] Switch the CGSCC debug messages to use the standard LLVM debug
Thu, Aug 10, 10:48 PM

Wed, Aug 9

chandlerc committed rL310547: [LCG] Fix an assert in a on-scope-exit lambda that checked the contents.
[LCG] Fix an assert in a on-scope-exit lambda that checked the contents
Wed, Aug 9, 8:06 PM
chandlerc added a comment to D36562: [Bitfield] Make the bitfield a separate location if it has width of legal integer type and its bit offset is naturally aligned for the type.

This has been discussed before and I still pretty strongly disagree with it.

Wed, Aug 9, 7:42 PM
chandlerc committed rL310456: [LCG] Completely remove the map-based association of post-order numbers.
[LCG] Completely remove the map-based association of post-order numbers
Wed, Aug 9, 2:38 AM
chandlerc committed rL310451: [LCG] Special case when removing a ref edge from a RefSCC leaves.
[LCG] Special case when removing a ref edge from a RefSCC leaves
Wed, Aug 9, 2:15 AM
chandlerc committed rL310450: [LCG] Switch one of the update methods for the LazyCallGraph to support.
[LCG] Switch one of the update methods for the LazyCallGraph to support
Wed, Aug 9, 2:08 AM
chandlerc closed D36352: [LCG] Switch one of the update methods for the LazyCallGraph to support limited batch updates. by committing rL310450: [LCG] Switch one of the update methods for the LazyCallGraph to support.
Wed, Aug 9, 2:08 AM

Tue, Aug 8

chandlerc added a comment to D36352: [LCG] Switch one of the update methods for the LazyCallGraph to support limited batch updates..

Thanks for the review all! I've fixed the mentioned issues and am landing based on Sean's LGTM.

Tue, Aug 8, 4:41 AM
chandlerc added a comment to D35851: [Dominators] Include infinite loops in PostDominatorTree.

I need to think about these. Some LLVM-IR unit tests that explain the property you are looking for would make the discussion here more concrete, as I will need some time to translate your textual ideas to IR. Even without, I certainly will have a look at your pointers.

Tue, Aug 8, 4:04 AM
chandlerc committed rL310342: [PM] Fix a likely more critical infloop bug in the CGSCC pass manager..
[PM] Fix a likely more critical infloop bug in the CGSCC pass manager.
Tue, Aug 8, 3:14 AM

Mon, Aug 7

chandlerc committed rL310334: [PM] Relax the spelling of a pass name slightly in this test..
[PM] Relax the spelling of a pass name slightly in this test.
Mon, Aug 7, 7:28 PM
chandlerc committed rL310333: [PM] Fix new LoopUnroll function pass by invalidating loop analysis.
[PM] Fix new LoopUnroll function pass by invalidating loop analysis
Mon, Aug 7, 7:25 PM
chandlerc accepted D36333: Move the SampleProfileLoader right after EarlyFPM..

ping...

I think Chandler's concerns for this patch has been addressed. We can continue discussion on the AutoFDO design in a separate thread. Will submit the patch by EOD if no more concerns have been raised.

Mon, Aug 7, 11:18 AM

Sun, Aug 6

chandlerc added a comment to D36352: [LCG] Switch one of the update methods for the LazyCallGraph to support limited batch updates..

Really nice analysis. I hadn't gotten that far, so that is helpful. Sadly, the descriptor stuff being the source isn't too surprising to me.

Sun, Aug 6, 3:19 PM

Sat, Aug 5

chandlerc committed rL310189: [ADT] Add a much simpler loop to DenseMap::clear when the types are.
[ADT] Add a much simpler loop to DenseMap::clear when the types are
Sat, Aug 5, 3:49 PM
chandlerc added a comment to D36352: [LCG] Switch one of the update methods for the LazyCallGraph to support limited batch updates..

When compiling the IR for this file with 'opt' and 'O3', this patch reduces the total time by 8-9%.

Just as a point of reference, do you have handy how much of the total compile time are we spending in the PM's CGSCC / LCG stuff?

Sat, Aug 5, 3:18 PM
chandlerc created D36352: [LCG] Switch one of the update methods for the LazyCallGraph to support limited batch updates..
Sat, Aug 5, 5:21 AM
chandlerc committed rL310174: [LCG] Remove yet another variable only used inside of asserts..
[LCG] Remove yet another variable only used inside of asserts.
Sat, Aug 5, 1:34 AM
chandlerc committed rL310171: [LCG] Completely remove the parent set and leaf tracking for RefSCCs..
[LCG] Completely remove the parent set and leaf tracking for RefSCCs.
Sat, Aug 5, 12:37 AM

Fri, Aug 4

chandlerc committed rL310170: [LCG] Re-implement the basic isParentOf, isAncestorOf, isChildOf, and.
[LCG] Re-implement the basic isParentOf, isAncestorOf, isChildOf, and
Fri, Aug 4, 11:24 PM
chandlerc committed rL310169: [LCG] Add the concept of a "dead" node and use it to avoid a complex.
[LCG] Add the concept of a "dead" node and use it to avoid a complex
Fri, Aug 4, 10:48 PM
chandlerc committed rL310165: [LCG] Replace an implicit bool operator with a named function. (NFC).
[LCG] Replace an implicit bool operator with a named function. (NFC)
Fri, Aug 4, 9:05 PM
chandlerc committed rL310164: [LCG] When removing a dead function and clearing out the data.
[LCG] When removing a dead function and clearing out the data
Fri, Aug 4, 8:38 PM
chandlerc committed rL310162: [LCG] Remove the complex walk of the parent sets to update graph.
[LCG] Remove the complex walk of the parent sets to update graph
Fri, Aug 4, 8:38 PM
chandlerc committed rL310163: [LCG] Rather than walking the directed graph structure to update graph.
[LCG] Rather than walking the directed graph structure to update graph
Fri, Aug 4, 8:38 PM
chandlerc committed rL310161: [LCG] Remove the use of the parent sets to compute connectivity when.
[LCG] Remove the use of the parent sets to compute connectivity when
Fri, Aug 4, 8:38 PM
chandlerc added inline comments to D36333: Move the SampleProfileLoader right after EarlyFPM..
Fri, Aug 4, 1:25 PM

Thu, Aug 3

chandlerc accepted D36199: [Inliner] Increase threshold for hot callsites without PGO..

LGTM, thanks!

Thu, Aug 3, 2:54 PM

Wed, Aug 2

chandlerc added a comment to D36258: Disable loop peeling during full unrolling pass..

Perhaps it is cleaner to

  1. pass the information whether it is a full unroll to tryToUnroll
  2. add a internal option FullUnrollAllowPeeling and make it off by default? This will be similar to UnrollAllowPeeling flag, but takes precedence if it is full unroll.
Wed, Aug 2, 10:58 PM
chandlerc added a comment to D35850: [InlineCost] Add cl::opt to allow full inline cost to be computed for debugging purposes..

Why abandon? FWIW, this does seem really useful. I'd also suggest wiring it up so that when optimization remarks are enabled, we do the extra compile time work to give that a detailed answer. (Or maybe set a *really high* threshold below which we give a reasonably exact answer...)

Wed, Aug 2, 4:10 PM
chandlerc added a comment to D36199: [Inliner] Increase threshold for hot callsites without PGO..

While the total size increase doesn't concern me much, the >10% code size growth in some benchmarks is a bit concerning. Do these benchmarks also improve performance? If so, then this might be fine in general (once the -Os behavior is fixed, see below). However, if the benchmarks that are growing in size by a lot aren't also getting faster, then it seems a hard sell at O2 where we expect size increase to be at least generally associated with performance wins.

Naturally, this seems completely fine at O3 either way.

There are 5 tests in the test-suite with text size increase > 10% and > 4K. Three of them improve and two don't. For performance numbers, I used the perf tool to collect uops_retired:any on an Intel Xeon E5-2690 since the running time of these are small and noisy.

Test - Size increase KB (%) - Performance improvement

MultiSource/Benchmarks/VersaBench/beamformer - 5K(41.6%) - None
SingleSource/Benchmarks/Linpack/linpack-pc - 7K(36.4%) - +2%
MultiSource/Benchmarks/FreeBench/pifft - 18K(33%) - None
MultiSource/Benchmarks/tramp3d-v4 - 148K(20.7%) - 18%
SingleSource/Benchmarks/Adobe-C++/loop_unroll - 44K(17.6%) - 9%

The C/C++ subset of SPEC2006 increases by 0.5%. Two benchmarks improve in performance: 453.povray (+1.5%) and 473.astar (+1.81%).

Wed, Aug 2, 4:08 PM
chandlerc added a comment to D36199: [Inliner] Increase threshold for hot callsites without PGO..

Hi Easwaran,

What if the callee of a hot callsite also has a inline hint?

(FWIW, my 2 cents here would be that this should win over inline hint, as it should be quite a bit stronger. Anyways, will let Easwaran actually respond as well as I'm curious what he thinks.)

I initially started with a multiplier instead of an absolute threshold, but changed it mainly to be consistent with the PGO based hot callsite. It is definitely a stronger hint, but I think an argument can be made that various "signals" should be composed.

Wed, Aug 2, 12:06 PM
chandlerc accepted D36157: [PM] Split LoopUnrollPass and make partial unroller a function pass.

Looks great, thanks for this restructuring.

Wed, Aug 2, 11:56 AM
chandlerc added a comment to D36199: [Inliner] Increase threshold for hot callsites without PGO..

Hi Easwaran,

What if the callee of a hot callsite also has a inline hint?

Wed, Aug 2, 9:54 AM
chandlerc added a comment to D36059: [memops] Add a new pass to inject fast-path code for specific library function calls..

I have size data now.

Wed, Aug 2, 3:52 AM

Tue, Aug 1

chandlerc added a comment to D36199: [Inliner] Increase threshold for hot callsites without PGO..

While the total size increase doesn't concern me much, the >10% code size growth in some benchmarks is a bit concerning. Do these benchmarks also improve performance? If so, then this might be fine in general (once the -Os behavior is fixed, see below). However, if the benchmarks that are growing in size by a lot aren't also getting faster, then it seems a hard sell at O2 where we expect size increase to be at least generally associated with performance wins.

Tue, Aug 1, 7:36 PM
chandlerc committed rL309784: [PM] Fix a bug where through CGSCC iteration we can get.
[PM] Fix a bug where through CGSCC iteration we can get
Tue, Aug 1, 7:10 PM
chandlerc closed D36188: [PM] Fix a bug where through CGSCC iteration we can get infinite-inlining across multiple runs of the inliner by keeping a tiny history of internal-to-SCC inlining decisions. by committing rL309784: [PM] Fix a bug where through CGSCC iteration we can get.
Tue, Aug 1, 7:10 PM
chandlerc accepted D36195: Fix the bug that parseAAPipeline is not invoked in runNewPMPasses in release compiler..

LGTM as well FWIW, but happy to defer to Davide here.

Tue, Aug 1, 7:05 PM
chandlerc added a comment to D36188: [PM] Fix a bug where through CGSCC iteration we can get infinite-inlining across multiple runs of the inliner by keeping a tiny history of internal-to-SCC inlining decisions..

Thanks all, landing.

Tue, Aug 1, 7:01 PM