For a PL/pgSQL function, use the special variable FOUND:
CREATE FUNCTION foo(int, text)
  RETURNS void
  LANGUAGE plpgsql AS
$func$
BEGIN
   INSERT INTO table1 (id, value)
   VALUES ($1, $2)
   ON CONFLICT DO NOTHING;
   IF NOT FOUND THEN
      INSERT INTO table2 (table1_id, value)
      VALUES ($1, $2);
      UPDATE table3
      SET   (table1_id, time)
          = ($1       , now())
      WHERE  ???;  -- you don't want to update all rows in table3?
   END IF;
END
$func$;
Call:
SELECT foo(1, 'a');
FOUND is set to false if the INSERT does not actually insert any rows.
The manual about the ON CONFLICT Clause:
ON CONFLICT DO NOTHING simply avoids inserting a row as its
alternative action.
The manual about Obtaining the Result Status
UPDATE, INSERT, and DELETE statements set FOUND true if at least one
row is affected, false if no row is affected.
To be clear, this runs the later statements if a row in table1 does already exist, so the new row is not inserted. (Like you requested, but contrary to your question title.)
If you just want to check whether a row exists:
Race condition?
If subsequent commands in the same transaction depend on the (yet unlocked) existing row in table1 (with a FK for instance), you'll want to lock it to defend against concurrent transactions deleting or updating it in the meantime. One way to do this: instead of DO NOTHING use DO UPDATE, but do not actually update the row. The row is still locked:
INSERT INTO table1 AS t (id, value)
VALUES ($1, $2)
ON     CONFLICT (id) DO UPDATE  -- specify unique column(s) or constraint / index
SET    id = t.id WHERE false;   -- never executed, but locks the row
Obviously, if you can rule out concurrent transactions that might write to the same row in a conflicting manner, then the problem does not exist.
Detailed explanation: